真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

MySQL中binlog有什么用

這篇文章將為大家詳細(xì)講解有關(guān)MySQL中binlog有什么用,小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

10年的侯馬網(wǎng)站建設(shè)經(jīng)驗(yàn),針對(duì)設(shè)計(jì)、前端、開(kāi)發(fā)、售后、文案、推廣等六對(duì)一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。成都全網(wǎng)營(yíng)銷的優(yōu)勢(shì)是能夠根據(jù)用戶設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整侯馬建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無(wú)論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。創(chuàng)新互聯(lián)建站從事“侯馬網(wǎng)站設(shè)計(jì)”,“侯馬網(wǎng)站推廣”以來(lái),每個(gè)客戶項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。

一、binlog文件和文件的邏輯、物理表現(xiàn)形式

1. binlog文件

binlog文件主要包括:

  1. mysql-bin.000001

  2. mysql-bin.index

其中:

mysql-bin.index內(nèi)保存著server中未purge的binlog文件,以“文本”形式保留的。

2.binlog文件格式

mysql-bin.index沒(méi)啥可說(shuō)的,我們專門看一下二進(jìn)制binlog文件。

binlog文件格式有以下特點(diǎn):

  1. binlog是由event組成,event是binlog的邏輯最小單元。

  2. 文件頭的頭四個(gè)字節(jié)為BINLOG_MAGIC(fe 62 69 6e)

  3. 緊接著這四個(gè)字節(jié)的是 descriptor event : FORMAT_DESCRIPTION_EVENT

  4. 文件的末尾是 log-rotation event: ROTATE_EVENT

  5. 這兩個(gè)event中間是各種不同的event,每個(gè)event代表Master上不同的操作。

下面對(duì)基本比較關(guān)鍵的概念進(jìn)行說(shuō)明:

  • BINLOG_MAGIC

利用hexdump -C 讀取mysql-bin.000005的內(nèi)容,

這里分別以十六進(jìn)制和ASCII碼展示顯示,我們可以看到binlog的頭四個(gè)字節(jié)是固定的:fe 62 69 6e,后三個(gè)字符ASCII碼為bin,指明展示一個(gè)binlog文件。這四個(gè)字節(jié)成為 BINLOG_MAGIC。

  • event

mysqlbinlog -vvv 讀取mysql-bin.000011的內(nèi)容示例:

這里可以看到,第一個(gè)event是FORMAT_DESCRIPTION_EVENT,它記錄了這個(gè)binlog的版本(MySQL 5.0以后binlog 的版本都是4)。最后一個(gè)event,是ROTATE_EVENT,它記錄了切換到下一個(gè)binlog文件的文件名。

在它們兩個(gè)之間是各種其他的event,目前的event類型有:



enum Log_event_type { 
    UNKNOWN_EVENT= 0, 
    START_EVENT_V3= 1, 
    QUERY_EVENT= 2, 
    STOP_EVENT= 3, 
    ROTATE_EVENT= 4, 
    INTVAR_EVENT= 5, 
    LOAD_EVENT= 6, 
    SLAVE_EVENT= 7, 
    CREATE_FILE_EVENT= 8, 
    APPEND_BLOCK_EVENT= 9, 
    EXEC_LOAD_EVENT= 10, 
    DELETE_FILE_EVENT= 11, 
    NEW_LOAD_EVENT= 12, 
    RAND_EVENT= 13, 
    USER_VAR_EVENT= 14, 
    FORMAT_DESCRIPTION_EVENT= 15, 
    XID_EVENT= 16, 
    BEGIN_LOAD_QUERY_EVENT= 17, 
    EXECUTE_LOAD_QUERY_EVENT= 18, 
    TABLE_MAP_EVENT = 19, 
    PRE_GA_WRITE_ROWS_EVENT = 20, 
    PRE_GA_UPDATE_ROWS_EVENT = 21, 
    PRE_GA_DELETE_ROWS_EVENT = 22, 
    WRITE_ROWS_EVENT = 23, 
    UPDATE_ROWS_EVENT = 24, 
    DELETE_ROWS_EVENT = 25, 
    INCIDENT_EVENT= 26, 
    HEARTBEAT_LOG_EVENT= 27, 
    IGNORABLE_LOG_EVENT= 28,
    ROWS_QUERY_LOG_EVENT= 29,
    WRITE_ROWS_EVENT = 30,
    UPDATE_ROWS_EVENT = 31,
    DELETE_ROWS_EVENT = 32,
    GTID_LOG_EVENT= 33,
    ANONYMOUS_GTID_LOG_EVENT= 34,
    PREVIOUS_GTIDS_LOG_EVENT= 35, 
    ENUM_END_EVENT 
    /* end marker */ 
  };
  

當(dāng)然,內(nèi)部已經(jīng)有部分event被棄用了,我們不一一列舉,這里只簡(jiǎn)單介紹幾個(gè)平時(shí)經(jīng)常見(jiàn)到的:

  • QUERY_EVENT :用于具體的SQL文本。如果binlog_format=statement方式下,insert,update,delete等各種SQL都是以Query event記錄下來(lái)的。

  • WRITE_ROWS_EVENT,UPDATE_ROWS_EVENT,DELETE_ROWS_EVENT : 在binlog_format=row方式下,insert,update,delete操作的行信息分別以這三種event記錄下來(lái)。

  • GTID_LOG_EVENT:5.6的GTID模式下,每個(gè)事務(wù)的GTID序號(hào)被記錄到這種EVENT中。

  • PREVIOUS_GTIDS_LOG_EVENT :5.6的GTID模式下,這個(gè)event記錄了生成這個(gè)binlog之前,MySQL已經(jīng)執(zhí)行的所有事務(wù)的GTID集合

二、slave io在源碼中是怎么連上Master的

這里主要描述源碼中的函數(shù)調(diào)用關(guān)系

1. slave如何注冊(cè)并請(qǐng)求master 的binlog

slave io線程對(duì)應(yīng)的入口函數(shù)為sql/rpl_slave.cc:handle_slave_io()

該函數(shù)核心主要是做了以下三個(gè)事情:

  1. safe_connect(thd, mysql, mi)

  2. register_slave_on_master(mysql, mi, &suppress_warnings)

  3. request_dump(thd, mysql, mi, &suppress_warnings)

  4. event_len= read_event(mysql, mi, &suppress_warnings);

也就是說(shuō),它先以標(biāo)準(zhǔn)的連接方式連上master MySQL,然后把自己注冊(cè)到master上去,接著調(diào)用request_dump向master請(qǐng)求binlog數(shù)據(jù),最后一個(gè)一個(gè)event讀取并存放到本地relay log中。

  • safe_connect

連接MySQL的標(biāo)準(zhǔn)方式,MySQL c的connector也是用這種方式連接MySQL server的。

  • register_slave_on_master

slave把自己的slave_id,IP,端口,用戶名提交給Master,用于注冊(cè)自己到Master上去。

  • request_dump

根據(jù)GTID來(lái)進(jìn)行判斷,如果是GTID模式,那么把本地執(zhí)行的GTID集合及其他相關(guān)信息傳給master;如果不是GTID模式,那么就把master log file和Pos傳給主庫(kù)。主庫(kù)如何根據(jù)這些信息來(lái)發(fā)送binlog的event,參考下節(jié)。

  • read_event

read_event調(diào)用了cli_safe_read(),cli_safe_read()調(diào)用了my_net_read(),等待主庫(kù)將binlog數(shù)據(jù)發(fā)過(guò)來(lái)

也就是說(shuō),read_event被動(dòng)的從網(wǎng)絡(luò)中接受主庫(kù)發(fā)過(guò)來(lái)的信息。

2. master 如何處理slave的 binlog 請(qǐng)求

MySQL處理各種命令的核心函數(shù)為:sql/sql_parse.cc:dispatch_command

該函數(shù)會(huì)根據(jù)用戶的請(qǐng)求來(lái)確定做什么事情,

  • COM_REGISTER_SLAVE則調(diào)用register_slave(thd, (uchar*)packet, packet_length)注冊(cè)slave

  • COM_BINLOG_DUMP_GTID 則調(diào)用com_binlog_dump_gtid(thd, packet, packet_length);

  • COM_BINLOG_DUMP 則調(diào)用com_binlog_dump(thd, packet, packet_length);

我們這里以com_binlog_dump為例介紹master怎么發(fā)送binlog event給slave的。

com_binlog_dump核心代碼為:

  1. kill_zombie_dump_threads(&slave_uuid);

  2. mysql_binlog_send(thd, thd->strdup(packet + 10), (my_off_t) pos, NULL)

kill_zombie_dump_threads()函數(shù):如果新的server_id相同的slave注冊(cè)上來(lái),master會(huì)移除跟該slave的server_id匹配的的binlog dump線程

com_binlog_dump()會(huì)調(diào)用mysql_binlog_send()來(lái)打開(kāi)文件,將文件指針挪到指定位置,讀取文件,將一個(gè)個(gè)的event按照事件順序發(fā)給slave。

綜上

MySQL復(fù)制需要slave先注冊(cè)到Master,再向Master提交binlog和POS,請(qǐng)求發(fā)送binlog。Master接收到請(qǐng)求后,先做一系列驗(yàn)證,打開(kāi)本地binlog文件,按照內(nèi)部event的順序,依序發(fā)給slave。

三、sql線程在源碼中是怎么讀取二進(jìn)制信息,應(yīng)用到本地MySQL的

sql線程在5.6引入了db級(jí)別的并行,所以有兩個(gè)入口

1

2

handle_slave_worker

  handle_slave_sql

handle_slave_worker線程是主要干活的函數(shù),handle_salve_sql函數(shù)作為協(xié)調(diào)器會(huì)啟動(dòng)和分配worker線程。

handle_slave_sql函數(shù)主要調(diào)用了slave_worker_exec_job。

slave_worker_exec_job的主要功能:

  1. job_item= pop_jobs_item(worker, job_item); ev= static_cast(job_item->data);

  2. error= ev->do_apply_event_worker(worker);

該函數(shù)做到事情其實(shí)就是 從handle_salve_sql()獲得具體的event(ev),然后調(diào)用ev->do_apply_event_worker(worker),利用c++的多態(tài)特性,調(diào)用真正的event的do_apply_event虛函數(shù),以便將不同的event的操作在本地做一遍。

這里需要大家回顧一下event的概念了,event是binlog的最小單元,所有的event的父類是Log_event(抽象基類),它定義了一系列虛函數(shù),其中就包括我們這里調(diào)用的函數(shù):

這里舉一個(gè)insert語(yǔ)句對(duì)應(yīng)的的Write_rows_log_event例子,簡(jiǎn)單說(shuō)明一下數(shù)據(jù)是怎么應(yīng)用到本地MySQL的。

Write_rows_log_event,Update_rows_log_event和Delete_rows_log_event的do_apply_event都是調(diào)用的它的基類Rows_log_event的do_apply_event。

Rows_log_event的do_apply_event主要功能如下:

  1. m_table= const_cast (rli)->m_table_map.get_table(m_table_id);

  2. error= (this->*do_apply_row_ptr)(rli);

get_table()先從table map中獲得對(duì)應(yīng)的table的信息,然后調(diào)用do_apply_row_ptr函數(shù)指針指向的函數(shù)來(lái)將event對(duì)應(yīng)操作應(yīng)用到本地MySQL。

do_apply_row_ptr函數(shù)指針可能指向以下幾種不同的函數(shù):

  • do_hash_scan_and_update

  • do_index_scan_and_update

  • do_table_scan_and_update

  • do_apply_row

Write_rows_log_event是insert,不用查找數(shù)據(jù),所以它調(diào)用的是do_apply_row。

do_apply_row主要的功能就是調(diào)用了do_exec_row ….汗

do_exec_row是Write_rows_log_event自己實(shí)現(xiàn)的,它的主要功能是調(diào)用了 write_row ….汗

write_row也是Write_rows_log_event自己實(shí)現(xiàn)的,它的主要功能是:m_table->file->ha_start_bulk_insert(estimated_rows);也就是說(shuō),它直接把這一行數(shù)據(jù)交給了存儲(chǔ)引擎,讓存儲(chǔ)引擎把數(shù)據(jù)給插進(jìn)去。

四、binlog_format=ROW 格式下,MySQL是怎么用二進(jìn)制保存各種不同的數(shù)據(jù)類型的

在sql/log_event.cc:log_event_print_value()函數(shù)中詳細(xì)描述了MySQL的各種數(shù)據(jù)類型的二進(jìn)制表現(xiàn)形式,摘錄如下

這里有幾個(gè)比較有意思的地方:

  1. MYSQL_TYPE_STRING 類型,它的length占用的字節(jié)數(shù)是不固定的。如果string長(zhǎng)度不到大于255,則需要占用2個(gè)字節(jié),所以,MySQL在定義String類型的字段時(shí),255是一個(gè)坎,如果字段不可能超過(guò)255個(gè)字節(jié),不建議定義長(zhǎng)度的時(shí)候超過(guò)255,否則MySQL存儲(chǔ)數(shù)據(jù)時(shí)會(huì)白白浪費(fèi)一個(gè)字節(jié)。

  2. MYSQL_TYPE_DATETIME類型。它存儲(chǔ)的格式就是把年-月-日 時(shí):分:秒按順序存儲(chǔ)下來(lái)的,比如:2015-10-10 22:45:55存儲(chǔ)下來(lái)就存儲(chǔ)為20151010224545。這種存儲(chǔ)格式比較浪費(fèi),所以字節(jié)數(shù)相比timestamp占用的也比較多。

關(guān)于“MySQL中binlog有什么用”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。


分享文章:MySQL中binlog有什么用
網(wǎng)站URL:http://weahome.cn/article/iiheed.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部