All posts by admin

Como evitar “The “default” context does not exist.” quando se corre tasks do doctrine em symfony 1.4

O erro acontece devido ao uso do sfContext::getInstance() no código.

Temos duas formas de possível correcção:

Ou se edita a task em questão e se coloca

1
sfContext::createInstance($this->configuration)

para criar um context.

Ou se cria o contexto no código:

1
2
$configuration = ProjectConfiguration::getApplicationConfiguration('frontend', 'doctrine', false);
$context = sfContext::createInstance($configuration);

MySQL count(1) count(*) Myth

Sometimes people say that you should use select count(1) from table; instead select count(*) from table; because is faster, if you read some good books on MySQL they never refer this optimisation (strange).

So a little testing:

mysql> explain extended select sql_no_cache count(*) from lc_contact_detail \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: lc_contact_detail
type: index
possible_keys: NULL
key: contact_id
key_len: 4
ref: NULL
rows: 13393816
filtered: 100.00
Extra: Using index
1 row in set, 1 warning (0.00 sec)

mysql> explain extended select sql_no_cache count(1) from lc_contact_detail \G
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: lc_contact_detail
type: index
possible_keys: NULL
key: contact_id
key_len: 4
ref: NULL
rows: 13393849
filtered: 100.00
Extra: Using index
1 row in set, 1 warning (0.00 sec)

Looks MySQL will execute the  query in the same way in either case, if didn’t convince you, profile:

mysql> select sql_no_cache count(*) from lc_contact_detail;
+———-+
| count(*) |
+———-+
| 13457066 |
+———-+
1 row in set (5.64 sec)

mysql> show profile for query 1;
+——————–+———-+
| Status             | Duration |
+——————–+———-+
| starting           | 0.033511 |
| Opening tables     | 0.000019 |
| System lock        | 0.000007 |
| Table lock         | 0.000012 |
| init               | 0.000016 |
| optimizing         | 0.000008 |
| statistics         | 0.000015 |
| preparing          | 0.000012 |
| executing          | 0.000007 |
| Sending data       | 5.606788 |
| end                | 0.000018 |
| query end          | 0.000005 |
| freeing items      | 0.000059 |
| logging slow query | 0.000004 |
| cleaning up        | 0.000006 |
+——————–+———-+
15 rows in set (0.02 sec)

mysql> select sql_no_cache count(1) from lc_contact_detail;
+———-+
| count(1) |
+———-+
| 13457088 |
+———-+
1 row in set (5.54 sec)

mysql> show profile for query 2;
+——————–+———-+
| Status             | Duration |
+——————–+———-+
| starting           | 0.000077 |
| Opening tables     | 0.000020 |
| System lock        | 0.000007 |
| Table lock         | 0.000011 |
| init               | 0.000017 |
| optimizing         | 0.000007 |
| statistics         | 0.000013 |
| preparing          | 0.000011 |
| executing          | 0.000008 |
| Sending data       | 5.545308 |
| end                | 0.000019 |
| query end          | 0.000006 |
| freeing items      | 0.000058 |
| logging slow query | 0.000004 |
| cleaning up        | 0.000006 |
+——————–+———-+
15 rows in set (0.00 sec)

Is actually the same. So feel free to use one form or another. count(*) looks better IMO

Prevent wrong rm -rf

I writted the following function to prevent wrong rm -rf:

function rm() {
rf_detected=0
for arg in “$@”
do
if [[ $arg == -*r*f* ]]
then
rf_detected=1
fi
done
if [ $rf_detected -eq 1 ]
then
echo “-rf detected. Action stoped.”
else
/bin/rm “$@”
fi
}

To use just put it at the end of .bashrc, this way if you use rm -rf you will get a message, so you have to think twice and to really remove use /bin/rm -rf …

Be careful about the use of this function, for example if some crontabs have inside them source ~/.bashrc they will use this function too, so at them you need to use /bin/rm.

Another way (not so good) to avoid this to add at this function a check of $PPID if it belongs to to bash you use, but this can be tricky too, see this example:

eoliveira@local:~$ echo $PPID
1870
eoliveira@local:~$ cat /proc/1870/cmdline
/usr/bin/python/usr/bin/terminator

eoliveira@local:~$ echo $PPID
4119
eoliveira@local:~$ cat /proc/4119/cmdline
gnome-terminal

root@blogs:/var/www# echo $PPID
27808
root@blogs:/var/www# cat /proc/27808/cmdline
sudo-i-u root

You can do in another way and check if the thing running is a crontab.

Crontab, prevent duplicate process

Sometimes you want to use crontab to run some scripts from time to time, but you are not sure how much it will take. And you want to avoid run more than one process of the script at the same time.

This will do the trick:

*/MINUTES    *       *       *       *       if [ `ps aux | grep NAME | grep -v “grep” | wc -l` -eq 0 ]; then  /…/NAME  ; fi

MySQL Error: Illegal mix of collations

Say you wanted to do a simple join such as:

1
SELECT count(1) FROM table_a a LEFT OUTER JOIN table_b b ON (a.varchar_column = b.varchar_column) WHERE b.varchar_column IS NULL;

And you got:

1
ERROR 1267 (HY000): Illegal mix of collations (utf8_general_ci,IMPLICIT) and (utf8_unicode_ci,IMPLICIT) for operation '='

All you need to do is update your table’s charset AND collation:

1
ALTER TABLE table_b CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;

PS – table_b or table_a, whichever you decide that should match the other’s charset and collation.

Apc para o Doctrine em projectos symfony

Em projectos symfony 1.*, pode ser configurado o uso da cache Apc para o Doctrine, para tal, em config/ProjectConfiguration.class.php, criar o método:

public function configureDoctrine(Doctrine_Manager $manager)
{
$manager->setAttribute(Doctrine::ATTR_QUERY_CACHE, new Doctrine_Cache_Apc(array(‘prefix’ => ‘PREFIXO’)));
}

É importante definir um prefixo, já que tendo vários projectos na máquina, usando a mesma chave, gera conflito.