亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

  免費(fèi)注冊 查看新帖 |

Chinaunix

  平臺 論壇 博客 文庫
最近訪問板塊 發(fā)新帖
查看: 1825 | 回復(fù): 0
打印 上一主題 下一主題

mydumper0.23版本的使用和源代碼分析 [復(fù)制鏈接]

論壇徽章:
2
2015年辭舊歲徽章
日期:2015-03-03 16:54:1515-16賽季CBA聯(lián)賽之上海
日期:2016-05-05 09:45:14
跳轉(zhuǎn)到指定樓層
1 [收藏(0)] [報(bào)告]
發(fā)表于 2011-12-23 01:34 |只看該作者 |倒序?yàn)g覽

mydumper是一個多線程、高性能的數(shù)據(jù)邏輯備份、恢復(fù)的工具,相比MySQL自帶的mysqldump提速不少。我下載了0.23的穩(wěn)定版本,閱讀了源碼并總結(jié)了一些使用的心得。

mysqldump是個單線程的邏輯備份工具,依次一個個導(dǎo)出多個表,沒有一個并行的機(jī)制。mydumper彌補(bǔ)了這方面的缺陷可以并行的多線程的從表中讀入數(shù)據(jù)并同時(shí)寫到不同的文件里。項(xiàng)目的作者是由一群在sun、fb、skysql的工程師完成的。類似的工具還有mk-parallel-dump。

編譯安裝cmake . make sudo make install 源碼分析

根據(jù)流程圖解釋一下mydumper的工作步驟。

解析參數(shù)
使用glib的g_option_context_parse,比libc里的getopt_long簡單多了。

連接目標(biāo)數(shù)據(jù)庫。

通過show processlist來判斷是否有長查詢,如果有長查詢則退出dump,可以通過–long-query-guard加長時(shí)間,或者使用–kill-long-queries殺掉長查詢。

鎖定myisam表。

針對innodb table開啟事務(wù)。

產(chǎn)生3個消息隊(duì)列(線程ready隊(duì)列、任務(wù)隊(duì)列、myisam表處理完畢隊(duì)列)。

conf.queue = g_async_queue_new(); conf.ready = g_async_queue_new(); conf.unlock_tables= g_async_queue_new();

產(chǎn)生指定的線程個數(shù),–threads可以指定,默認(rèn)是4個。

GThread **threads = g_new(GThread*,num_threads); struct thread_data *td= g_new(struct thread_data, num_threads); for (n=0; n<num_threads; n++) { td[n].conf= &conf; td[n].thread_id= n+1; threads[n] = g_thread_create((GThreadFunc)process_queue,&td[n],TRUE,NULL); g_async_queue_pop(conf.ready); }

dump_database,從DATA_DICTIONARY.TABLES讀取所有表,通過–ignore, –tables-list, regex等過濾條件,產(chǎn)生需要dump的目標(biāo)表列表,分別插入innodb_tables、non_innodb_table、 table_schemas三個鏈表。

query= g_strdup_printf("SELECT TABLE_NAME, ENGINE, TABLE_TYPE as COMMENT FROM DATA_DICTIONARY.TABLES WHERE TABLE_SCHEMA='%s'", database); .... innodb_tables= g_list_append(innodb_tables, dbt); .... non_innodb_table= g_list_append(non_innodb_table, dbt); .... table_schemas= g_list_append(table_schemas, dbt);

dump non-innodb table 把需要導(dǎo)出myisam表加入到任務(wù)隊(duì)列。

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); }

dump innodb table把需要導(dǎo)出innodb表加入任務(wù)隊(duì)列。

for (innodb_tables= g_list_first(innodb_tables); innodb_tables; innodb_tables= g_list_next(innodb_tables)) { dbt= (struct db_table*) innodb_tables->data; dump_table(conn, dbt->database, dbt->table, &conf, TRUE); }

dump schema 把需要導(dǎo)出表結(jié)構(gòu)任務(wù)加入到任務(wù)隊(duì)列。

for (table_schemas= g_list_first(table_schemas); table_schemas; table_schemas= g_list_next(table_schemas)) { dbt= (struct db_table*) table_schemas->data; dump_schema(dbt->database, dbt->table, &conf); g_free(dbt->table); g_free(dbt->database); g_free(dbt); }

典型的生產(chǎn)者(主線程)消費(fèi)者(子線程)模式,子線程會從任務(wù)隊(duì)列里讀取需要處理的表名字和表類型,再通過select * from table_name 讀入數(shù)據(jù)各自寫入到各自的文件。

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); }

所有導(dǎo)數(shù)據(jù)的任務(wù)加入任務(wù)隊(duì)列之后,會再加入讓線程退出的任務(wù),讓線程自然退出。

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;

解除myisam表鎖。

等待子線程退出。

使用

導(dǎo)出test database的數(shù)據(jù)

mydumper -h 127.0.0.1 -u root --database test

指定某個目錄

mydumper -h 127.0.0.1 -u root --outputdir=.

不導(dǎo)出表結(jié)構(gòu)

mydumper -h 127.0.0.1 -u root --no-schema

如果表數(shù)據(jù)是空,還是產(chǎn)生一個空文件(默認(rèn)無數(shù)據(jù)則只有表結(jié)構(gòu)文件)

mydumper -h 127.0.0.1 -u root --build-empty-files

設(shè)置長查詢的上限,如果存在比這個還長的查詢則退出mydumper,也可以設(shè)置殺掉這個長查詢

mydumper -h 127.0.0.1 -u root --long-query-guard 200 --kill-long-queries

設(shè)置要dump的列表–tables-list,不需要設(shè)置db名字,逗號分割

mydumper -h 127.0.0.1 -u root --tables-list=ddd,zzz

通過regex也設(shè)置正則表達(dá),需要設(shè)置db名字

mydumper -h 127.0.0.1 -u root --regex=test.z

把單表分成多個chunks,這個后面會講分割的原理

mydumper -h 127.0.0.1 -u root --rows 10000

過濾某個引擎的表

mydumper -h 127.0.0.1 -u root -B test --ignore-engines=innodb

詳細(xì)日志

mydumper -h 127.0.0.1 -u root -B test -v 3 幾個注意點(diǎn)

各自線程都要自己連接到數(shù)據(jù)庫,因?yàn)閘ibmysql是線程不安全的。
因?yàn)閷yisam表有有表鎖,所有先處理myisam表,記錄myisam表個數(shù),每處理一個myisam都原子操作數(shù)量減一。并在myisam表都處理完畢后,立即解鎖,盡量減少鎖定的時(shí)間,而不是在導(dǎo)出innodb表數(shù)據(jù)的時(shí)候還在lock myisam表。

main_thread

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

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

g_async_queue_pop(conf.unlock_tables); g_message("Non-InnoDB dump complete, unlocking tables"); mysql_query(conn, "UNLOCK TABLES");

–regex的處理在–tables-list后, 先滿足–tables-list再滿足–regex,如下只會dump表z1

mydumper -h 127.0.0.1 -u root --regex=test.z1 --outputdir=. --rows=10000 -v 3 -e --tables-list=z2,z1 ** Message: Thread 1 dumping data for `test`.`z1` ** Message: Thread 2 dumping schema for `test`.`z1`

–rows的使用,設(shè)置–rows可以把一個表分成多個文件。分塊的原則并不是根據(jù)–rows設(shè)定的行數(shù)來決定生成文件里包含的函數(shù),而是通過rows和表的總行數(shù)計(jì)算出要生成的文件個數(shù),盡量保證每個文件的大小一致。

表的總行數(shù)是如何獲得的?
首先mydumper會選擇一個索引,順序是pk、uk或者show index from table里Cardinality最高的一個索引,再通過explain select index from table的rows字段獲得總行數(shù)total_nums(可能不準(zhǔn)確),于是第一個文件就是從select * from table where index >=1 and index < total_nums/ (int(total_nums/ rows) – 1) + 1。每個分塊可以分到不同的線程,所以即便同一個表dump都可以很快加速。

ps:這個項(xiàng)目大量使用glib(gnome)比較少見,看了一下glib doc覺得glib設(shè)計(jì)的挺好的用起來很方便,否則實(shí)現(xiàn)一個消息隊(duì)列加多線程還是要幾百行代碼的。接下來要看mydumper0.50的代碼。

作者: hoterran

原文鏈接地址:http://www.hoterran.info/mydumper_usage

myumper源碼下載地址:http://www.mydumper.org/?p=23

您需要登錄后才可以回帖 登錄 | 注冊

本版積分規(guī)則 發(fā)表回復(fù)

  

北京盛拓優(yōu)訊信息技術(shù)有限公司. 版權(quán)所有 京ICP備16024965號-6 北京市公安局海淀分局網(wǎng)監(jiān)中心備案編號:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年舉報(bào)專區(qū)
中國互聯(lián)網(wǎng)協(xié)會會員  聯(lián)系我們:huangweiwei@itpub.net
感謝所有關(guān)心和支持過ChinaUnix的朋友們 轉(zhuǎn)載本站內(nèi)容請注明原作者名及出處

清除 Cookies - ChinaUnix - Archiver - WAP - TOP