国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
mysqldump的流程 | OurMySQL

    前幾天看到群里在討論mysqldump導(dǎo)致鎖表的問題,為什么一個(gè)表已經(jīng)dump完了還會(huì)被鎖???mysqldump里面到底是怎么處理的,為了解答這些問題,就來看看mysqldump.cc中的實(shí)現(xiàn)吧。

重要參數(shù)

   首先我們把參數(shù)和內(nèi)部變量對應(yīng)起來,并且看一下它們的注釋:

-single-transaction: opt_single_transaction

   Creates a consistent snapshot by dumping all tables in a single transaction. Works ONLY for tables stored in storage engines which support multiversioning (currently only InnoDB does); the dump is NOT guaranteed to be consistent for other storage engines. While a -single-transaction dump is in process, to ensure a valid dump file (correct table contents and binary log position), no other connection should use the following statements: ALTER TABLE, DROP TABLE, RENAME TABLE, TRUNCATE TABLE, as consistent snapshot is not isolated from them. Option automatically turns off -lock-tables.

   通過將導(dǎo)出操作封裝在一個(gè)事務(wù)內(nèi)來使得導(dǎo)出的數(shù)據(jù)是一個(gè)一致性快照。只有當(dāng)表使用支持MVCC的存儲(chǔ)引擎(目前只有InnoDB)時(shí)才可以工作;其他引擎不能保證導(dǎo)出是一致的。當(dāng)導(dǎo)出開啟了-single-transaction選項(xiàng)時(shí),要確保導(dǎo)出文件有效(正確的表數(shù)據(jù)和二進(jìn)制日志位置),就要保證沒有其他連接會(huì)執(zhí)行如下語句:ALTER TABLE, DROP TABLE, RENAME TABLE, TRUNCATE TABLE,這會(huì)導(dǎo)致一致性快照失效。這個(gè)選項(xiàng)開啟后會(huì)自動(dòng)關(guān)閉lock-tables。

-master-data: opt_master_data

   This causes the binary log position and filename to be appended to the output. If equal to 1, will print it as a CHANGE MASTER command; if equal to 2, that command will be prefixed with a comment symbol. This option will turn -lock-all-tables on, unless -single-transaction is specified too (in which case a global read lock is only taken a short time at the beginning of the dump; don’t forget to read about -single-transaction below). In all cases, any action on logs will happen at the exact moment of the dump. Option automatically turns -lock-tables off.

   這個(gè)選項(xiàng)可以把binlog的位置和文件名添加到輸出中,如果等于1,將會(huì)打印成一個(gè)CHANGE MASTER命令;如果等于2,會(huì)加上注釋前綴。并且這個(gè)選項(xiàng)會(huì)自動(dòng)打開-lock-all-tables,除非同時(shí)設(shè)置了-single-transaction(這種情況下,全局讀鎖只會(huì)在開始dump的時(shí)候加上一小段時(shí)間,不要忘了閱讀-single-transaction的部分)。在任何情況下,所有日志中的操作都會(huì)發(fā)生在導(dǎo)出的準(zhǔn)確時(shí)刻。這個(gè)選項(xiàng)會(huì)自動(dòng)關(guān)閉-lock-tables。

-lock-all-tables: opt_lock_all_tables

   Locks all tables across all databases. This is achieved by taking a global read lock for the duration of the whole dump. Automatically turns -single-transaction and -lock-tables off.

   鎖定所有庫中所有的表。這是通過在整個(gè)dump的過程中持有全局讀鎖來實(shí)現(xiàn)的。會(huì)自動(dòng)關(guān)閉-single-transaction 和 -lock-tables。

-lock-tables: lock_tables

   Lock all tables for read. (Defaults to on; use -skip-lock-tables to disable.)

   對所有表加讀鎖。(默認(rèn)是打開的;用-skip-lock-tables來關(guān)閉)

-flush-logs: flush_logs

   Flush logs file in server before starting dump. Note that if you dump many databases at once (using the option -databases= or -all-databases), the logs will be flushed for each database dumped. The exception is when using -lock-all-tables or -master-data: in this case the logs will be flushed only once, corresponding to the moment all tables are locked. So if you want your dump and the log flush to happen at the same exact moment you should use -lock-all-tables or -master-data with -flush-logs。

   在開始導(dǎo)出前刷新服務(wù)器的日志文件。注意,如果你一次性導(dǎo)出很多數(shù)據(jù)庫(使用 -databases= 或 -all-databases 選項(xiàng)),導(dǎo)出每個(gè)庫時(shí)都會(huì)觸發(fā)日志刷新。例外是當(dāng)使用了 -lock-all-tables 或 -master-data 時(shí):日志只會(huì)被刷新一次,那個(gè)時(shí)候所有表都會(huì)被鎖住。所以如果你希望你的導(dǎo)出和日志刷新發(fā)生在同一個(gè)確定的時(shí)刻,你需要使用-lock-all-tables,或者 -master-data 配合 -flush-logs。

-delete-master-logs: opt_delete_master_logs

   Delete logs on master after backup. This automatically enables -master-data.

   備份完成后刪除主庫上的日志。這個(gè)選項(xiàng)會(huì)自動(dòng)打開 -master-data.

-apply-slave-statements: opt_slave_apply(5.5)

   Adds ‘STOP SLAVE’ prior to ‘CHANGE MASTER’ and ‘START SLAVE’ to bottom of dump.

   在’CHANGE MASTER’前加上’STOP SLAVE’,在導(dǎo)出文件的末尾加上’START SLAVE’.

主要代碼流程

   我們分別看一下5.1和5.5的代碼,都基于最新的trunk(5.1-rev.3909; 5.5-rev.4148)。

5.1版本主要流程

   我們首先看下5.1版本的。

5320   if ((opt_lock_all_tables || opt_master_data) &&5321       do_flush_tables_read_lock(mysql))5322     goto err;

   如果設(shè)置了master-data或lock-all-tables,則做FLUSH TABLES的操作。

   來看下do_flush_tables_read_lock()里面是怎么做的,

do_flush_tables_read_lock()4665   return4666     ( mysql_query_with_error_report(mysql_con, 0, 4667                                     ((opt_master_data != 0) ? // 如果設(shè)置了--master-data4668                                         "FLUSH /*!40101 LOCAL */ TABLES" : // 那么用FLUSH LOCAL TABLES 4669                                         "FLUSH TABLES")) || // 如果沒設(shè)置那么使用FLUSH TABLE4670       mysql_query_with_error_report(mysql_con, 0,4671                                     "FLUSH TABLES WITH READ LOCK") ); // 如果上面的語句執(zhí)行成功了,再執(zhí)行這個(gè)

   先FLUSH TABLES,成功后用FLUSH TABLES WITH READ LOCK加全局讀鎖。

   再往下會(huì)判斷single-transaction,

5323   if (opt_single_transaction && start_transaction(mysql))5324       goto err;

   如果定義了-single-transaction則打開一個(gè)事務(wù)來讀取數(shù)據(jù)。

   我們看下start_transaction()的實(shí)現(xiàn),

start_transaction()4741   return (mysql_query_with_error_report(mysql_con, 0,4742                                         "SET SESSION TRANSACTION ISOLATION "4743                                         "LEVEL REPEATABLE READ") || // 先設(shè)置會(huì)話的隔離級別為RR4744           mysql_query_with_error_report(mysql_con, 0,4745                                         "START TRANSACTION "4746                                         "/*!40100 WITH CONSISTENT SNAPSHOT */")); // 再用一致性快照模式(RR)啟動(dòng)事務(wù)

   會(huì)先設(shè)置隔離級別為RR,然后START TRANSACTION加上一致性快照的Hint。

   接下來是獲取Master的狀態(tài),

5338   if (opt_master_data && do_show_master_status(mysql))5339     goto err;

   如果設(shè)置了-master-data 則把當(dāng)前的Master status打印出來。

   接下來再判斷如果啟用了-single-transaction,則可以釋放表鎖的,因?yàn)槭聞?wù)已經(jīng)啟動(dòng)了。

5340   if (opt_single_transaction && do_unlock_tables(mysql)) /* unlock but no commit! */5341     goto err;

   do_unlock_tables()里面就發(fā)一條UNLOCK TABLES語句釋放全局表鎖。

do_unlock_tables()4677   return mysql_query_with_error_report(mysql_con, 0, "UNLOCK TABLES");

   然后開始調(diào)用dump_*函數(shù)根據(jù)需要導(dǎo)出整個(gè)實(shí)例或者一個(gè)庫或者一個(gè)表。

dump_all_databases()->dump_all_tables_in_db()4307   if (lock_tables)4308   {4309     DYNAMIC_STRING query;4310     init_dynamic_string_checked(&query, "LOCK TABLES ", 256, 1024);4311     for (numrows= 0 ; (table= getTableName(1)) ; )4312     {4313       char *end= strmov(afterdot, table);4314       if (include_table((uchar*) hash_key,end - hash_key))4315       {4316         numrows++;4317         dynstr_append_checked(&query, quote_name(table, table_buff, 1));4318         dynstr_append_checked(&query, " READ /*!32311 LOCAL */,");                                                                                                  4319       }4320     }4321     if (numrows && mysql_real_query(mysql, query.str, query.length-1))4322       DB_error(mysql, "when using LOCK TABLES");4323             /* We shall continue here, if --force was given */4324     dynstr_free(&query);4325   }/* 如果設(shè)置了--lock-tables(默認(rèn)),則導(dǎo)出之前需要LOCK TABLES tables_name READ。*/...4332   while ((table= getTableName(0)))4333   {4334     char *end= strmov(afterdot, table);4335     if (include_table((uchar*) hash_key, end - hash_key))4336     {4337       dump_table(table,database); // 導(dǎo)出一張表4338       my_free(order_by, MYF(MY_ALLOW_ZERO_PTR));4339       order_by= 0;4340       if (opt_dump_triggers && mysql_get_server_version(mysql) >= 50009)4341       {4342         if (dump_triggers_for_table(table, database)) // 導(dǎo)出 trigger4343         {4344           if (path)4345             my_fclose(md_result_file, MYF(MY_WME));4346           maybe_exit(EX_MYSQLERR);4347         }4348       }4349     }4350   } /* 先dump_table來導(dǎo)出表,然后再看是不是配置了--triggers來決定是不是導(dǎo)出Trigger,dump_triggers_for_table。*/...4366   if (lock_tables)4367     VOID(mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES")); /* 導(dǎo)出完成之后,釋放表鎖 */

   所以我們可以知道,如果用-master-data和-single-transaction來導(dǎo)出數(shù)據(jù),因?yàn)?lock-tables被自動(dòng)關(guān)閉,所以導(dǎo)出過程中只會(huì)對當(dāng)前正在做導(dǎo)出操作的表有IS鎖,已經(jīng)完成或沒有開始的表,則不會(huì)加鎖。

   如果用的是默認(rèn)-lock-tables打開的選項(xiàng),則會(huì)先把所有庫的鎖加上,再進(jìn)行導(dǎo)出操作,最后一次性釋放所有鎖。

5.5版本主要流程

   接下來我們再比較一下,5.5的mysqldump有哪些變化。

5464   if ((opt_lock_all_tables || opt_master_data ||5465        (opt_single_transaction && flush_logs)) &&5466       do_flush_tables_read_lock(mysql))5467     goto err;

   這里有所不同,增加了flush_logs的判斷,如果只是單純的-single-transaction,不會(huì)調(diào)用do_flush_tables_read_lock(),必須同時(shí)制定-flush-logs。

5469   /*5470     Flush logs before starting transaction since5471     this causes implicit commit starting mysql-5.5.5472   */5473   if (opt_lock_all_tables || opt_master_data ||5474       (opt_single_transaction && flush_logs) ||5475       opt_delete_master_logs)5476   {5477     if (flush_logs || opt_delete_master_logs)5478     {5479       if (mysql_refresh(mysql, REFRESH_LOG))5480         goto err;5481       verbose_msg("-- main : logs flushed successfully!\n");5482     }5483 5484     /* Not anymore! That would not be sensible. */5485     flush_logs= 0;5486   }

   5.5里面會(huì)嘗試FLUSH LOGS。

5488   if (opt_delete_master_logs)5489   {5490     if (get_bin_log_name(mysql, bin_log_name, sizeof(bin_log_name)))5491       goto err;5492   }

   5.5新增的變量,刪除master上的log,這里先獲取binlog的文件名。

5494   if (opt_single_transaction && start_transaction(mysql))5495     goto err;

   這一段沒有變化

5497   /* Add 'STOP SLAVE to beginning of dump */5498   if (opt_slave_apply && add_stop_slave())5499     goto err;5500   if (opt_master_data && do_show_master_status(mysql))5501     goto err;5502   if (opt_slave_data && do_show_slave_status(mysql))5503     goto err;5504   if (opt_single_transaction && do_unlock_tables(mysql)) /* unlock but no commit! */5505     goto err;

   這里有新加的opt_slave_apply和opt_slave_data部分,添加STOP SLAVE語句和顯示SHOW SALVE STATUS的結(jié)果。

   之后也是調(diào)用dump_*來導(dǎo)出數(shù)據(jù)。

   但是因?yàn)?.5有了MDL(Meta data lock),所以-single-transaction時(shí),事務(wù)內(nèi)操作過的表都會(huì)持有MDL,因此不會(huì)被DDL破壞。

覺得文章有用?立即: 和朋友一起 共學(xué)習(xí) 共進(jìn)步!

猜您喜歡

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊舉報(bào)。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
MySQL主從切換
MySQL完全備份、增量備份與恢復(fù)
mysql基于二進(jìn)制文件的主從復(fù)制
14、數(shù)據(jù)庫備份基礎(chǔ)知識
XtraBackup工具詳解 Part 3 XtraBackup工作原理
redis數(shù)據(jù)丟失及解決
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服