J'ai récemment découvert qu'une requête SQL qui fonctionnait bien auparavant expirait maintenant après 60 secondes et renvoyait une erreur. La requête est lente mais fonctionne dans le cadre d'un travail nocturne, donc ce n'est pas un problème en soi (donc, ne suggérez pas que je l'optimise).
Je suis capable de reproduire l'erreur systématiquement en exécutant "select SLEEP (120);" de PHP comme indiqué ci-dessous. Toutefois, l’exécution de la même instruction à partir d’un client MySQL réussit (renvoie 0). J'ai essayé d'ajuster wait_timeout (défini sur 28800), mais je n'ai pas eu de chance. J'ai également redémarré le serveur de base de données et la machine elle-même.
Le fait que le délai expire toujours à exactement 60 secondes me laisse supposer qu'il s'agira probablement d'un problème de paramètre et non de ressources limitées.
Je suis entrain de courir:
Windows Server 2003
MySql 5.1.36-community
PHP 5.3
Vous trouverez ci-dessous mon code de test, la sortie et les résultats de SHOW VARIABLES.
Merci!
CODE:
set_error_handler("sqlErrorHandler");
set_time_limit(12000);
$link = mysql_connect("$MYSQL_Host","$MYSQL_User","$MYSQL_Pass");
mysql_select_db($MYSQL_db, $link);
echo "mysql_ping = " . (mysql_ping($link) ? "LIVE" : "DEAD") . "<br /><br />";
$sql = "SELECT SLEEP(120);";
$start = microtime(true);
mysql_query($sql, $link);
echo "**query done**<br />";
allDone();
function allDone(){
global $start, $sql;
$end = microtime(true);
echo "sql : $sql<br />";
echo "elapsed : " . ($end - $start) . "<br />";
echo "<br />";
}
function sqlErrorHandler($errno, $errstr, $errfile, $errline){
global $link;
echo "Error : $errno<br />$errstr<br />";
echo "mysql_ping : " . (mysql_ping($link) ? "LIVE" : "DEAD") . "<br />";
echo "<br />";
allDone();
}
SORTIE:
mysql_ping = LIVE
Error : 2
mysql_query() [function.mysql-query]: MySQL server has gone away
mysql_ping : DEAD
sql : SELECT SLEEP(120);
elapsed : 60.051116943359
Error : 2
mysql_query() [function.mysql-query]: Error reading result set's header
mysql_ping : DEAD
sql : SELECT SLEEP(120);
elapsed : 60.0511469841
**query done**
sql : SELECT SLEEP(120);
elapsed : 60.051155090332
MONTRER LES VARIABLES:
Variable_name=Value
auto_increment_increment=1
auto_increment_offset=1
autocommit=ON
automatic_sp_privileges=ON
back_log=50
basedir=C:\\Program Files\\MySQL\\MySQL Server 5.1\\
big_tables=OFF
binlog_cache_size=32768
binlog_format=STATEMENT
bulk_insert_buffer_size=8388608
character_set_client=utf8
character_set_connection=utf8
character_set_database=latin1
character_set_filesystem=binary
character_set_results=utf8
character_set_server=latin1
character_set_system=utf8
character_sets_dir=C:\\Program Files\\MySQL\\MySQL Server 5.1\\share\\charsets\\
collation_connection=utf8_general_ci
collation_database=latin1_swedish_ci
collation_server=latin1_swedish_ci
completion_type=0
concurrent_insert=1
connect_timeout=10
datadir=C:\\Documents and Settings\\All Users\\Application Data\\MySQL\\MySQL Server 5.1\\Data\\
date_format=%Y-%m-%d
datetime_format=%Y-%m-%d %H:%i:%s
default_week_format=0
delay_key_write=ON
delayed_insert_limit=100
delayed_insert_timeout=300
delayed_queue_size=1000
div_precision_increment=4
engine_condition_pushdown=ON
error_count=0
event_scheduler=OFF
expire_logs_days=0
flush=OFF
flush_time=1800
foreign_key_checks=ON
ft_boolean_syntax=+ -><()~*:""&|
ft_max_Word_len=84
ft_min_Word_len=4
ft_query_expansion_limit=20
ft_stopword_file=(built-in)
general_log=OFF
general_log_file=C:\\Documents and Settings\\All Users\\Application Data\\MySQL\\MySQL Server 5.1\\Data\\p1.log
group_concat_max_len=1024
have_community_features=YES
have_compress=YES
have_crypt=NO
have_csv=YES
have_dynamic_loading=YES
have_geometry=YES
have_innodb=YES
have_ndbcluster=NO
have_openssl=DISABLED
have_partitioning=YES
have_query_cache=YES
have_rtree_keys=YES
have_ssl=DISABLED
have_symlink=YES
identity=0
ignore_builtin_innodb=OFF
init_connect=
init_file=
init_slave=
innodb_adaptive_hash_index=ON
innodb_additional_mem_pool_size=2097152
innodb_autoextend_increment=8
innodb_autoinc_lock_mode=1
innodb_buffer_pool_size=96468992
innodb_checksums=ON
innodb_commit_concurrency=0
innodb_concurrency_tickets=500
innodb_data_file_path=ibdata1:10M:autoextend
innodb_data_home_dir=D:\\MySQL Datafiles\\
innodb_doublewrite=ON
innodb_fast_shutdown=1
innodb_file_io_threads=4
innodb_file_per_table=OFF
innodb_flush_log_at_trx_commit=1
innodb_flush_method=
innodb_force_recovery=0
innodb_lock_wait_timeout=50
innodb_locks_unsafe_for_binlog=OFF
innodb_log_buffer_size=1048576
innodb_log_file_size=19922944
innodb_log_files_in_group=2
innodb_log_group_home_dir=.\\
innodb_max_dirty_pages_pct=90
innodb_max_purge_lag=0
innodb_mirrored_log_groups=1
innodb_open_files=300
innodb_rollback_on_timeout=OFF
innodb_stats_on_metadata=ON
innodb_support_xa=ON
innodb_sync_spin_loops=20
innodb_table_locks=ON
innodb_thread_concurrency=8
innodb_thread_sleep_delay=10000
innodb_use_legacy_cardinality_algorithm=ON
insert_id=0
interactive_timeout=28800
join_buffer_size=131072
keep_files_on_create=OFF
key_buffer_size=50331648
key_cache_age_threshold=300
key_cache_block_size=1024
key_cache_division_limit=100
language=C:\\Program Files\\MySQL\\MySQL Server 5.1\\share\\english\\
large_files_support=ON
large_page_size=0
large_pages=OFF
last_insert_id=0
lc_time_names=en_US
license=GPL
local_infile=ON
log=OFF
log_bin=OFF
log_bin_trust_function_creators=OFF
log_bin_trust_routine_creators=OFF
log_error=C:\\Documents and Settings\\All Users\\Application Data\\MySQL\\MySQL Server 5.1\\Data\\p1.err
log_output=FILE
log_queries_not_using_indexes=OFF
log_slave_updates=OFF
log_slow_queries=OFF
log_warnings=1
long_query_time=10.000000
low_priority_updates=OFF
lower_case_file_system=ON
lower_case_table_names=1
max_allowed_packet=1048576
max_binlog_cache_size=4294963200
max_binlog_size=1073741824
max_connect_errors=10
max_connections=800
max_delayed_threads=20
max_error_count=64
max_heap_table_size=16777216
max_insert_delayed_threads=20
max_join_size=18446744073709551615
max_length_for_sort_data=1024
max_prepared_stmt_count=16382
max_relay_log_size=0
max_seeks_for_key=4294967295
max_sort_length=1024
max_sp_recursion_depth=0
max_tmp_tables=32
max_user_connections=0
max_write_lock_count=4294967295
min_examined_row_limit=0
multi_range_count=256
myisam_data_pointer_size=6
myisam_max_sort_file_size=107374182400
myisam_recover_options=OFF
myisam_repair_threads=1
myisam_sort_buffer_size=12582912
myisam_stats_method=nulls_unequal
myisam_use_mmap=OFF
named_pipe=OFF
net_buffer_length=16384
net_read_timeout=30
net_retry_count=10
net_write_timeout=80
new=OFF
old=OFF
old_alter_table=OFF
old_passwords=OFF
open_files_limit=2048
optimizer_Prune_level=1
optimizer_search_depth=62
optimizer_switch=index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on
pid_file=C:\\Documents and Settings\\All Users\\Application Data\\MySQL\\MySQL Server 5.1\\Data\\p1.pid
plugin_dir=C:\\Program Files\\MySQL\\MySQL Server 5.1\\lib/plugin
port=3306
preload_buffer_size=32768
profiling=OFF
profiling_history_size=15
protocol_version=10
pseudo_thread_id=3230
query_alloc_block_size=8192
query_cache_limit=1048576
query_cache_min_res_unit=4096
query_cache_size=33554432
query_cache_type=ON
query_cache_wlock_invalidate=OFF
query_prealloc_size=8192
Rand_seed1=
Rand_seed2=
range_alloc_block_size=4096
read_buffer_size=65536
read_only=OFF
read_rnd_buffer_size=262144
relay_log=
relay_log_index=
relay_log_info_file=relay-log.info
relay_log_purge=ON
relay_log_space_limit=0
report_Host=
report_password=
report_port=3306
report_user=
rpl_recovery_rank=0
secure_auth=OFF
secure_file_priv=
server_id=0
shared_memory=OFF
shared_memory_base_name=MYSQL
skip_external_locking=ON
skip_networking=OFF
skip_show_database=OFF
slave_compressed_protocol=OFF
slave_exec_mode=STRICT
slave_load_tmpdir=C:\\WINDOWS\\TEMP
slave_net_timeout=3600
slave_skip_errors=OFF
slave_transaction_retries=10
slow_launch_time=2
slow_query_log=OFF
slow_query_log_file=C:\\Documents and Settings\\All Users\\Application Data\\MySQL\\MySQL Server 5.1\\Data\\p1-slow.log
sort_buffer_size=262144
sql_auto_is_null=ON
sql_big_selects=ON
sql_big_tables=OFF
sql_buffer_result=OFF
sql_log_bin=ON
sql_log_off=OFF
sql_log_update=ON
sql_low_priority_updates=OFF
sql_max_join_size=18446744073709551615
sql_mode=
sql_notes=ON
sql_quote_show_create=ON
sql_safe_updates=OFF
sql_select_limit=18446744073709551615
sql_slave_skip_counter=
sql_warnings=OFF
ssl_ca=
ssl_capath=
ssl_cert=
ssl_cipher=
ssl_key=
storage_engine=InnoDB
sync_binlog=0
sync_frm=ON
system_time_zone=Eastern Daylight Time
table_definition_cache=256
table_lock_wait_timeout=50
table_open_cache=619
table_type=InnoDB
thread_cache_size=38
thread_handling=one-thread-per-connection
thread_stack=196608
time_format=%H:%i:%s
time_zone=SYSTEM
timed_mutexes=OFF
timestamp=1256827484
tmp_table_size=16777216
tmpdir=C:\\WINDOWS\\TEMP
transaction_alloc_block_size=8192
transaction_prealloc_size=4096
tx_isolation=REPEATABLE-READ
unique_checks=ON
updatable_views_with_limit=YES
version=5.1.36-community
version_comment=MySQL Community Server (GPL)
version_compile_machine=ia32
version_compile_os=Win32
wait_timeout=28800
warning_count=0
L'option php mysql.connect_timeout
en est la raison. Il n'est pas seulement utilisé pour le délai de connexion, mais aussi pour attendre la première réponse du serveur. Vous pouvez l'augmenter comme ceci:
ini_set('mysql.connect_timeout', 300);
ini_set('default_socket_timeout', 300);
Lorsque j'ai rencontré ce problème, il n'était pas causé par wait_timeout (défini sur la valeur par défaut de 8 heures), mais par max_allowed_packet avec une grande instruction INSERT. La modification de max_allowed_packet depuis PHP n'a eu aucun effet, mais lorsque je l'ai modifié dans la section mysqld de /etc/my.cnf et que j'ai redémarré le serveur MySQL, le problème a disparu.
Cela peut être causé par toute une série de facteurs. Je les lisais et essayais chacun d'entre eux
http://dev.mysql.com/doc/refman/5.1/en/gone-away.html
J'ai travaillé pour plusieurs sociétés d'hébergement Web au fil des ans et généralement, quand je vois cela, c'est l'attente sur le serveur, bien que cela ne semble pas être le cas ici.
Si vous trouvez la solution, j'espère que vous la posterez. J'aimerais savoir.
C'est quelque chose que je fais (mais généralement avec la classe MySQLi).
$link = mysql_connect("$MYSQL_Host","$MYSQL_User","$MYSQL_Pass");
mysql_select_db($MYSQL_db, $link);
// RUN REALLY LONG QUERY HERE
// Reconnect if needed
if( !mysql_ping($link) ) $link = mysql_connect("$MYSQL_Host","$MYSQL_User","$MYSQL_Pass", true);
// RUN ANOTHER QUERY
L'augmentation de SQL-Wait-Timeout a fonctionné pour moi dans ce cas, essayez ceci:
mysql_query("SET @@session.wait_timeout=900", $link);
avant de commencer par les requêtes SQL "normales".
J'ai résolu ce problème avec
if( !mysql_ping($link) ) $link = mysql_connect("$MYSQL_Host","$MYSQL_User","$MYSQL_Pass", true);
Mon cas était une corruption de base de données après une mise à niveau mineure dans mysql, à savoir les versions 5.0.x à 5.1.x Avec la base de données dans myisam . Les mêmes lignes de la requête: Le serveur MySQL a disparu. lecture de l'en-tête du jeu de résultats
Après l'avoir réparé et optimisé avec mysqlcheck, il est revenu à la normale, sans qu'il soit nécessaire de modifier le délai d'attente du socket.
J'ai eu ce problème récemment. Je suis tombé sur une option: default_authentication_plugin
Pour une raison quelconque, il l'avait défini sur caching_sha2_password
, mais la mise à jour de la valeur sur mysql_native_password
l'a corrigé pour moi. Je ne suis toutefois pas sûr des différences, alors faites attention!
J'espère que cela aide quelqu'un!
Dans notre cas, le coupable était la variable global (pas "locale") MySQL "wait_timeout".
Comparez les résultats des requêtes suivantes:
SHOW VARIABLES LIKE '%wait%';
à
SHOW GLOBAL VARIABLES WHERE Variable_name LIKE '%wait%';
Dans notre cas, la première requête indiquait un wait_timeout de 28800, mais la deuxième requête indiquait une valeur de 10 (secondes).
Nous avons vérifié que le changement de la variable globale corrigeait le problème. Voici un simple script PHP qui reproduit notre condition:
<?php
$db = mysqli_connect('Host', 'user', 'password', 'database');
sleep(10); // number of seconds to sleep
// MySQL server has gone away?
$obj = mysqli_query($db, 'SELECT * FROM some_table');
$results = mysqli_fetch_object($obj);
print_r($results);
Dès que le temps de repos dépasse la valeur globale wait_timeout, nous obtenons le message d'erreur suivant: "Avertissement: mysqli_query (): le serveur MySQL a disparu".
Pour modifier la valeur, nous avons dû modifier le paramètre dans notre tableau de bord Amazon RDS.
Cela se produit si la connexion était ouverte depuis un certain temps mais qu'aucune action n'a été effectuée sur le serveur MySQL. Dans ce cas, le délai de connexion est dépassé avec l'erreur "Le serveur MySQL est parti". Les réponses ci-dessus peuvent fonctionner et risquent de ne pas fonctionner. Même la réponse acceptée n'a pas fonctionné pour moi. Alors j'ai essayé un tour et ça a bien fonctionné pour moi. Logiquement, afin d'éviter cette erreur, nous devons maintenir la connexion MySQL en cours d'exécution ou, en bref, la garder active . Supposons que nous essayons de regrouper insérer 250 000 enregistrements. Généralement, il faut du temps pour créer des données d'analyse à partir de quelque part et faire Bulk query puis insérer. Dans ce scénario, la plupart d’entre nous utilisons une boucle pour créer la chaîne SQL. Compilons donc le nombre d’itérations et effectuons un appel de base de données factice après une certaine itération. Cela maintiendra la connexion en vie.
for(int i = 0, size = somedatalist.length; i < size; ++i){
// build the Bulk insert query string
if((i%10000)==0){
// make a dummy call like `SELECT * FROM log LIMIT 1`
// it will keep the connection alive
}
}
// Execute bulk insert
J'ai le même problème avec mysqli. Ma solution est http://php.net/manual/ru/mysqli.configuration.php
mysqli.reconnect = On
J'avais des problèmes sur une restauration de base de données en utilisant mysqldumper (programme php). J'ai réussi à le faire fonctionner en modifiant le paramètre "mssql.timeout" dans le fichier php.ini. Il a été configuré par défaut à 60 et je l'ai changé à 300.
J'ai remarqué quelque chose de pertinent peut-être.
J'avais deux scripts en cours d'exécution, les deux faisant des requêtes plutôt lentes. L'un d'eux a verrouillé une table et l'autre a dû attendre. Celui qui attendait avait default_socket_timeout = 300. Finalement, il s'est arrêté avec "Le serveur MySQL est parti". Cependant, la liste des processus mysql continuait d'afficher les deux requêtes, la plus lente toujours en cours d'exécution et l'autre bloquée et en attente.
Donc, je ne pense pas que mysqld soit le coupable. Quelque chose a changé dans le client php mysql. Probablement le default_socket_timeout que je vais maintenant mettre à -1 pour voir si cela change quelque chose.
D'après mes expériences, quand il s'agit de requêtes légères, il existe un moyen de résoudre le problème. Il semble que lorsque vous démarrez ou redémarrez mysql
après Apache
, ce problème commence à apparaître et la source du problème est confondue avec les sockets ouverts dans le processus php
. Pour le résoudre:
Premier redémarrage du service mysql
Puis redémarrez le service Apache