mydumper工作原理

hxw2ljj發表於2015-10-30

相比mysqldump,其優勢如下:

1 速度快(好多資料都說快10倍,個人持保留意見);

2 支援多執行緒匯出和匯入myloader;

3 採用守護程式方式執行,可定時掃描和快照binlog(-snapshot-interval);

4 快速檔案壓縮;

 

也有稍許不足之處,如mydumper不處理MySQL的檢視,觸發器和儲存過程,因此使用mydumper去匯出schema並不可靠。

實際生產環境中,建議mydumper僅用於匯出資料(使用 --no-schemas ),而透過mysqldump來匯出schema。

 

mydumper除了為每個表會分別生成table.sql和table-schema.sql,還會生成一個.metadata檔案,記錄dump的開始和結束時間,以及binlog位置資訊。

 

 

引數

-long-query-guard:長查詢上限(預設60s),如果當前資料庫存在執行時間大於此引數的查詢則退出mydumper;

-kill-long-queries:殺死查出的長查詢;

-daemon:啟用守護程式模式;

-snapshot-interval:快照時間間隔,預設60s;

-t, --threads 使用的執行緒數,預設4

-C, --compress-protocol 在mysql連線上使用壓縮

-e, --enable-binlog 啟用二進位制恢復資料

-r, --rows 將表分成多個檔案批次匯出,

  1 確定表的行數,依據pk – uk – cardinality最高的索引(show index from table)選擇索引,透過explain select index from table的rows欄位確定行數;

  2 已經total_rows和rows將表分成若干分塊,每個分塊可由不同worker並行執行,適用於大表;

 

 

安裝

1 安裝cmake,apt-get install cmake;

2 安裝相容包,如apt-get install libglib2.0-dev libmysqlclient15-dev,具體參照官網;

3 下載安裝包並編譯

#wget

#tar xzvf mydumper-0.2.3.tar.gz

#cd mydumper-0.2.3/

#cmake .

#make

#make install

 

 

原理

Mysqldump是個單執行緒工具,只能逐個匯出表,而mydumper支援多執行緒並行匯出;

儘管mydumper主執行緒已經登入進入了mysql,但worker子執行緒必須再登入一次,因為libmysql是執行緒不安全的?

 

 

工作流程

1  連線目標資料庫;

2  透過show processlist來判斷是否有長查詢,如果有長查詢則退出dump(透過-long-query-guard指定),或者使用-kill-long-queries殺掉長查詢;

3  鎖定myisam表,flush tables with read lock;  針對innodb table開啟事務,start transaction;

4  建立worker子執行緒;

5  確定候選表,根據類別分別插入innodb_table,non_innodb_table以及table_schemas連結串列(表結構);

6  將候選表透過g_async_queue_push加入任務佇列(佇列最後元素是thread shutdown),由worker子執行緒從佇列中讀取表資訊並執行資料匯出

for(;;) {

    ....

    job=(struct job *)g_async_queue_pop(conf->queue);

    ....

    switch (job->type) {

        case JOB_DUMP:

            ....

            dump_table_data_file(thrconn, tj->database, tj->table, tj->where, tj->filename);

            ....

        case JOB_DUMP_NON_INNODB:

            ....

            dump_table_data_file(thrconn, tj->database, tj->table, tj->where, tj->filename);

        case JOB_SCHEMA:

            ....

            dump_schema_data(thrconn, sj->database, sj->table, sj->filename);

 

}

當worker讀取到job_shutdown任務時,則會執行如下

case JOB_SHUTDOWN:

    g_message("Thread %d shutting down", td->thread_id);

    if (thrconn)

        mysql_close(thrconn);

    g_free(job);

    mysql_thread_end();

    return NULL;

    break;

7  執行unlock tables,處理完myisam表後立即解鎖,以減少鎖定時間;

Main_thread:記錄myisam數量

for (non_innodb_table= g_list_first(non_innodb_table); non_innodb_table; non_innodb_table= g_list_next(non_innodb_table)) {

        dbt= (struct db_table*) non_innodb_table->data;

        dump_table(conn, dbt->database, dbt->table, &conf, FALSE);

        g_atomic_int_inc(&non_innodb_table_counter);

}

 

child_thread:當佇列中myisam為0時,加入unlock_tables任務

if (g_atomic_int_dec_and_test(&non_innodb_table_counter) && g_atomic_int_get(&non_innodb_done)) {

        g_async_queue_push(conf->unlock_tables, GINT_TO_POINTER(1));

}

 

main_thread:主執行緒讀取unlock_tables任務並執行

g_async_queue_pop(conf.unlock_tables);

g_message("Non-InnoDB dump complete, unlocking tables");

mysql_query(conn, "UNLOCK TABLES");

8  等待worker退出;

 

 

Myloader將資料匯入資料庫,原理與mydumper類似。

-queries-per-transaction

-directory

 

 

參考資料

http://blogread.cn/it/article/4071

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/18796236/viewspace-1818793/,如需轉載,請註明出處,否則將追究法律責任。