过程分析:
今天在分析慢查询日志的时候,发现一些这样的语句:
#=======================================================================================
# Query_time: 2.652960 Lock_time: 0.000000 Rows_sent: 1309590 Rows_examined: 1309590
SET timestamp=1306474204;
SELECT /*!40001 SQL_NO_CACHE */ * FROM `categorylinks`;
#=======================================================================================
查询这个表的所有记录。在程序里面不可能有这样的业务存在。然后看了下产生的时间,是00:30,正是备份数据库的时间。莫非是备份数据库时的查询?
打开备份文件,看下对每个表的备份流程是怎么样的
#========================================================================================
1:LOCK TABLES `myt` WRITE;
2:/*!40000 ALTER TABLE `myt` DISABLE KEYS */;
3:INSERT INTO `myt` VALUES ('table ™ name'),('table ? name'),('table ™ name'),('table ™ name');
4:/*!40000 ALTER TABLE `myt` ENABLE KEYS */;
5:UNLOCK TABLES;
#=========================================================================================
mysqldump程序能够得到values里的值,肯定是查了整个表的,然后再在程序里拼好,形成insert语句。
在每个表的备份里面,都有“LOCK TABLES”,看看源码里是怎么操作的:
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if (opt_lock) #是否锁表的参数,就是mysqldump --help 看到的 --add-locks Add locks around INSERT statements.
{
fprintf(md_result_file,"LOCK TABLES %s WRITE;\n", opt_quoted_table); #如果是,打印lock table
check_io(md_result_file); #检查文件写入情况,每个地方都有,如果写入文件失败,就退出错误。
}
/* Moved disable keys to after lock per bug 15977 */
if (opt_disable_keys) #这里就是备份文件的第2行了
{
fprintf(md_result_file, "/*!40000 ALTER TABLE %s DISABLE KEYS */;\n",
opt_quoted_table);
check_io(md_result_file);
}
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
主要备份的数据是在第三行,看看是怎么处理的:
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
/*
If write_data is true, then we build up insert statements for
the table's data. Note: in subsequent lines of code, this test
will have to be performed each time we are appending to
insert_pat.
*/
if (write_data) #重点来了,看它怎么样拼SQL
{
if (opt_replace_into)
dynstr_append_checked(&insert_pat, "REPLACE "); #这些根据参数决定用INSERT ,REPLACE等插入方法
else
dynstr_append_checked(&insert_pat, "INSERT ");
dynstr_append_checked(&insert_pat, insert_option);
dynstr_append_checked(&insert_pat, "INTO ");
dynstr_append_checked(&insert_pat, opt_quoted_table);
if (complete_insert)
{
dynstr_append_checked(&insert_pat, " ("); #左边括号出现了
}
else
{
dynstr_append_checked(&insert_pat, " VALUES ");
if (!extended_insert)
dynstr_append_checked(&insert_pat, "(");
}
}
while ((row= mysql_fetch_row(result))) #在这里循环select * from tbname里的记录了
{
if (complete_insert)
{
if (init)
{
dynstr_append_checked(&insert_pat, ", "); #还在拼SQL
}
init=1;
dynstr_append_checked(&insert_pat,
quote_name(row[SHOW_FIELDNAME], name_buff, 0));
}
}
num_fields= mysql_num_rows(result);
mysql_free_result(result);
}
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
if (extended_insert)
{
ulong row_length;
dynstr_append_checked(&extended_row,")"); #反括号在这里出现了
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
代码写得很复杂,我断章取义挑出其中一部分看看,可能有地方不对,但是可以确定的一点是,mysqldump程序是要select * from tbname去获取数据的,而且如果表很大
这个查询时间很长的话,是会被记录到慢查询日志里的。
连接HOST和DB的函数
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
/*
db_connect -- connects to the host and selects DB.
*/
static int connect_to_db(char *host, char *user,char *passwd)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
查询表数据的函数
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
dynstr_append_checked(&query_string, "SELECT /*!40001 SQL_NO_CACHE */ * FROM ");
dynstr_append_checked(&query_string, result_table);
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
mysqldump的大概流程整理如下:
1:连接上数据库,根据输入的账户,密码,IP
2:进入INFORMATION_SCHEMA库,获取要备份的数据库的信息,包含存储过程,视图,表
3:进入INFORMATION_SCHEMA库,获取每个表的字段名称,字段类型等信息
4:查询每个表的数据,select SQL_NO_CACHE from tbname
5:拼SQL
6:写入备份文件
阅读(1393) | 评论(0) | 转发(0) |