亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

關(guān)于pt-archiver和自增主鍵的那些事

 更新時(shí)間:2022年04月25日 12:55:49   作者:yangyidba  
mysql是我們經(jīng)常會用到的一個(gè)數(shù)據(jù)庫,mysql數(shù)據(jù)庫中有一個(gè)主鍵生成規(guī)則,就是自增,這篇文章主要給大家介紹了關(guān)于pt-archiver和自增主鍵的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下

本文Percona Blog 的譯文,原文移步文章末尾的 閱讀原文。

前言

pt-archiver 是一款常見的 表清理或者歸檔工具。

MySQL 中刪除大表之前可以使用 pt-archiver 批量刪除所有記錄。這樣助于避免在某些情況下您的服務(wù)器可能會意外的情況,比如磁盤 IO 滿導(dǎo)致數(shù)據(jù)庫hang或者影響正常 SQL 慢查。

筆者最近遇到一個(gè)案例 ,有客戶反饋 "使用 pt-archiver  刪除數(shù)據(jù)時(shí),最后一行數(shù)據(jù)未被刪除。這個(gè)是不是bug?"

分析

在解決客戶的問題之前,我們需要解釋為什么在刪除大表之前使用 pt-archiver 當(dāng)我們在 MySQL 中刪除一個(gè)表時(shí), MySQL 系統(tǒng)會做如下動作:

刪除表數(shù)據(jù)/索引 (ibd) 和定義 (frm) 文件。
刪除觸發(fā)器。
通過刪除要刪除的表來更新表定義緩存。
掃描 InnoDB 緩沖池以查找關(guān)聯(lián)頁面以使其無效。--內(nèi)存到的表會遇到系統(tǒng)hang。

需要注意的是,DROP 是一個(gè) DDL 語句,它需要持有元數(shù)據(jù)鎖 (MDL) 才能完成,這樣會導(dǎo)致所有其他線程必須等待DDL完成,清除表相關(guān)的大量數(shù)據(jù)頁會對緩沖池產(chǎn)生額外的壓力。

最后,table_definition_cache 操作需要 LOCK_open mutex 來清理,這會導(dǎo)致所有其他線程等待直到刪除完成。

為了降低此操作的嚴(yán)重性,我們可以使用 pt-archiver 通過批量的形式刪除大量數(shù)據(jù),從而顯著降低表大小。一旦我們從大表中刪除了記錄,DROP 操作就會快速進(jìn)行而不會對系統(tǒng)性能產(chǎn)生影響。

社區(qū)成員注意到此行為,在 pt-archiver 完成后,該表仍有一行待處理。

#?Created?table
mysql>?CREATE?TABLE?`tt1`?(
??`id`?int(11)?NOT?NULL?AUTO_INCREMENT,
??`a`?char(5)?DEFAULT?NULL,
??PRIMARY?KEY?(`id`)
)?ENGINE=InnoDB

#?Poured?random?test?data?into?it
mysql>?call?populate('test','att1',10000,'N');

#?Purged?data?using?pt-archiver
[root@centos_2?~]#?pt-archiver?--source=h=localhost,D=test,t=tt1?--purge?--where?"1=1"

#?Verifying?count?(expected?0,?got?1)
mysql>?select?count(*)?from?test.tt1;
+----------+
|?count(*)?|
+----------+
|????????1?|
+----------+
1?row?in?set?(0.00?sec)

當(dāng)我們使用帶有 --no-delete 參數(shù)的 pt-archiver 進(jìn)行數(shù)據(jù)歸檔時(shí),也會發(fā)生同樣的情況。我們的工具 pt-archiver 似乎沒有將最大值復(fù)制到目標(biāo)表。

將表從?tt1?遷移到?tt2?
[root@centos_2?~]#?pt-archiver?--source=h=localhost,D=test,t=tt1?--dest=h=localhost,D=test,t=tt2?--no-delete?--where?"1=1"

mysql>?select?count(*)?from?tt2;
+----------+
|?count(*)?|
+----------+
|?????5008?|
+----------+
1?row?in?set?(0.00?sec)

mysql>?select?count(*)?from?tt1;
+----------+
|?count(*)?|
+----------+
|?????5009?|
+----------+
1?row?in?set?(0.00?sec)

解析

通讀 pt-archiver 文檔,有一個(gè)選項(xiàng) –[no]safe-auto-increment 描述了用法:“不要使用 max AUTO_INCREMENT 歸檔行。”

這意味著,選項(xiàng) –safe-auto-increment(默認(rèn))添加了一個(gè)額外的 WHERE 子句,以防止 pt-archiver 在提升單列 AUTO_INCREMENT 時(shí)刪除最新的行,如下面的代碼部分所示:

https://github.com/percona/percona-toolkit/blob/3.x/bin/pt-archiver#L6449
???if?(?$o->get('safe-auto-increment')
?????????&&?$sel_stmt->{index}
?????????&&?scalar(@{$src->{info}->{keys}->{$sel_stmt->{index}}->{cols}})?==?1
?????????&&?$src->{info}->{is_autoinc}->{
????????????$src->{info}->{keys}->{$sel_stmt->{index}}->{cols}->[0]
?????????}
???)?{
??????my?$col?=?$q->quote($sel_stmt->{scols}->[0]);
??????my?($val)?=?$dbh->selectrow_array("SELECT?MAX($col)?FROM?$src->{db_tbl}");
??????$first_sql?.=?"?AND?($col?<?"?.?$q->quote_val($val)?.?")";
???}

讓我們通過空運(yùn)行輸出看看這兩個(gè)命令之間的區(qū)別:

#?With?--no-safe-auto-increment
[root@centos_2?~]#?pt-archiver?--source=h=localhost,D=test,t=tt1?--dest=h=localhost,D=test,t=tt2?--no-delete?--where?"1=1"?<strong>--no-safe-auto-increment</strong>?--dry-run
SELECT?/*!40001?SQL_NO_CACHE?*/?`id`,`a`?FROM?`test`.`tt1`?FORCE?INDEX(`PRIMARY`)?WHERE?(1=1)?ORDER?BY?`id`?LIMIT?1
SELECT?/*!40001?SQL_NO_CACHE?*/?`id`,`a`?FROM?`test`.`tt1`?FORCE?INDEX(`PRIMARY`)?WHERE?(1=1)?AND?((`id`?>??))?ORDER?BY?`id`?LIMIT?1
INSERT?INTO?`test`.`tt2`(`id`,`a`)?VALUES?(?,?)
#?Without?--no-safe-auto-increment?(default)
[root@centos_2?~]#?pt-archiver?--source=h=localhost,D=test,t=tt1?--dest=h=localhost,D=test,t=tt2?--no-delete?--where?"1=1"?--dry-run
SELECT?/*!40001?SQL_NO_CACHE?*/?`id`,`a`?FROM?`test`.`tt1`?FORCE?INDEX(`PRIMARY`)?WHERE?(1=1)?<strong>AND?(`id`?<?'5009')</strong>?ORDER?BY?`id`?LIMIT?1
SELECT?/*!40001?SQL_NO_CACHE?*/?`id`,`a`?FROM?`test`.`tt1`?FORCE?INDEX(`PRIMARY`)?WHERE?(1=1)?<strong>AND?(`id`?<?'5009')</strong>?AND?((`id`?>??))?ORDER?BY?`id`?LIMIT?1
INSERT?INTO?`test`.`tt2`(`id`,`a`)?VALUES?(?,?)

注意到上面的附加子句 "AND ( id< '5009')" 了嗎?

如果服務(wù)器重新啟動,–no-safe-auto-increment 的這個(gè)選項(xiàng)可以防止重新使用 AUTO_INCREMENT 值。請注意,額外的 WHERE 子句包含自歸檔或清除作業(yè)開始時(shí)自增列的最大值。如果在 pt-archiver 運(yùn)行時(shí)插入新行,pt-archiver 將看不到它們。

好吧,現(xiàn)在我們知道了為什么沒有刪除干凈的“原因”,但為什么呢?AUTO_INCREMENT 的安全問題是什么?

AUTO_INCREMENT 計(jì)數(shù)器存儲在內(nèi)存中,當(dāng) MySQL 8.0之前的版本 重新啟動(崩潰或其他)時(shí),計(jì)數(shù)器將重置為最大值。如果發(fā)生這種情況并且表正在接受寫入,則 AUTO_INCREMENT 值將更改。

#?deleting?everything?from?table
mysql>?delete?from?tt1;
...
mysql>?show?table?status?like?'tt1'\G
***************************?1.?row?***************************
???????????Name:?tt1
?????????Engine:?InnoDB
...
?Auto_increment:?10019
...

#?Restarting?MySQL
[root@centos_2?~]#?systemctl?restart?mysql

#?Verifying?auto-increment?counter
[root@centos_2?~]#?mysql?test?-e?"show?table?status?like?'tt1'\G"
***************************?1.?row?***************************
???????????Name:?tt1
?????????Engine:?InnoDB
...
?Auto_increment:?1
...

上面的測試結(jié)果告訴我們: 這里的問題實(shí)際上并不在于 pt-archiver,而在于參數(shù)選項(xiàng)。在處理 AUTO_INCREMENT 列時(shí)使用 pt-archiver 時(shí),了解使用 –no-safe-auto-increment 選項(xiàng)很重要。

讓我們用我們的實(shí)驗(yàn)室數(shù)據(jù)來驗(yàn)證它。

#?Verifying?the?usage?of?–no-safe-auto-increment?option
[root@centos_2?~]#?pt-archiver?--source=h=localhost,D=test,t=tt1?--purge?--where?"1=1"?--no-safe-auto-increment

mysql>?select?count(*)?from?test.tt1;
+----------+
|?count(*)?|
+----------+
|????????0?|
+----------+
1?row?in?set?(0.00?sec)

使用 –no-delete 選項(xiàng)的復(fù)制操作也是如此。

[root@centos_2?~]#?pt-archiver?--source=h=localhost,D=test,t=tt1?--dest=h=localhost,D=test,t=tt2?--no-delete?--where?"1=1"?--no-safe-auto-increment

mysql>?select?count(*)?from?tt1;?select?count(*)?from?tt2;
+----------+
|?count(*)?|
+----------+
|?????5009?|
+----------+
1?row?in?set?(0.00?sec)

+----------+
|?count(*)?|
+----------+
|?????5009?|
+----------+
1?row?in?set?(0.00?sec)

通過上面的代碼和實(shí)際測試,我們知道了 pt-archiver 的 -[no]safe-auto-increment 選項(xiàng)的原理和作用 。在我們得出一切都很好的結(jié)論之前,讓我們多考慮一下選項(xiàng)本身存在的意義。

  • 默認(rèn)情況下,–no-delete 操作應(yīng)包含 –no-safe-auto-increment 選項(xiàng)。目前,safe-auto-increment 是默認(rèn)行為。當(dāng)我們使用 pt-archiver 的 --no-delete 選項(xiàng)時(shí),沒有刪除操作。這意味著 safe-auto-increment 不應(yīng)成為關(guān)注的原因。

  • 對于 MySQL 8.0,不需要 safe-auto-increment 選項(xiàng)。因?yàn)?MySQL 8.0 開始,自增的值是持久化的,并且在實(shí)例重新啟動或崩潰后自增的最大值不變。參考:MySQL 工作日志 https://dev.mysql.com/worklog/task/?id=6204

而且由于 MySQL 8.0 auto-increment 是通過重做日志持久化的,這使得它們成為pt-archiver 不關(guān)心的一個(gè)原因。因此,我們根本不需要 safe-auto-increment 選項(xiàng)。

結(jié)論

  • pt-archiver 是歸檔 MySQL 數(shù)據(jù)的好工具,重要的是要了解所有選項(xiàng)以完全控制我們想要使用它實(shí)現(xiàn)的目標(biāo)。

  • 以后需要根據(jù)自增id進(jìn)行歸檔的場景,pt-archiver 默認(rèn)最大的id不會進(jìn)行歸檔,需要添加參數(shù):--no-safe-auto-increment 才能對最大id進(jìn)行處理。

到此這篇關(guān)于pt-archiver和自增主鍵的文章就介紹到這了,更多相關(guān)pt-archiver和自增主鍵內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • mysql decimal數(shù)據(jù)類型轉(zhuǎn)換的實(shí)現(xiàn)

    mysql decimal數(shù)據(jù)類型轉(zhuǎn)換的實(shí)現(xiàn)

    這篇文章主要介紹了mysql decimal數(shù)據(jù)類型轉(zhuǎn)換的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • 如何解決MySQL5升級為MySQL8遇到的問題my.ini

    如何解決MySQL5升級為MySQL8遇到的問題my.ini

    這篇文章主要介紹了如何解決MySQL5升級為MySQL8遇到的問題my.ini,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • mysql中g(shù)eneral_log日志知識點(diǎn)介紹

    mysql中g(shù)eneral_log日志知識點(diǎn)介紹

    這篇文章主要介紹了mysql中g(shù)eneral_log日志知識點(diǎn)的介紹以及其他相關(guān)內(nèi)容,以后興趣的朋友們學(xué)習(xí)下。
    2019-08-08
  • MySQL子查詢的幾種常見形式介紹

    MySQL子查詢的幾種常見形式介紹

    mysql從4.1版開始支持子查詢功能,在此版本前,可以用join寫連表查詢來進(jìn)行替代,但不推薦這么寫,相當(dāng)?shù)穆闊?/div> 2014-04-04
  • MySQL函數(shù)date_format()日期格式轉(zhuǎn)換的實(shí)現(xiàn)

    MySQL函數(shù)date_format()日期格式轉(zhuǎn)換的實(shí)現(xiàn)

    本文主要介紹了MySQL函數(shù)date_format()日期格式轉(zhuǎn)換的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • mysql中union和union?all的使用及注意事項(xiàng)

    mysql中union和union?all的使用及注意事項(xiàng)

    這篇文章主要給大家介紹了關(guān)于mysql中union和union?all的使用及注意事項(xiàng)的相關(guān)資料,需要的朋友可以參考下
    2022-08-08
  • mysql創(chuàng)建表添加字段注釋的實(shí)現(xiàn)方法

    mysql創(chuàng)建表添加字段注釋的實(shí)現(xiàn)方法

    這篇文章主要介紹了mysql創(chuàng)建表添加字段注釋的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • MySQL中幾種插入和批量語句實(shí)例詳解

    MySQL中幾種插入和批量語句實(shí)例詳解

    這篇文章主要給大家介紹了關(guān)于MySQL中幾種插入和批量語句的相關(guān)資料,在mysql數(shù)據(jù)庫中,實(shí)現(xiàn)批量插入數(shù)據(jù)與批量更新數(shù)據(jù)的例子,即批量insert、update的方法,需要的朋友可以參考下
    2021-09-09
  • 利用Prometheus與Grafana對Mysql服務(wù)器的性能監(jiān)控詳解

    利用Prometheus與Grafana對Mysql服務(wù)器的性能監(jiān)控詳解

    Prometheus是源于 Google Borgmon的一個(gè)開源監(jiān)控系統(tǒng),用 Golang開發(fā)。被很多人稱為下一代監(jiān)控系統(tǒng)。Grafana是一個(gè)開源的圖表可視化系統(tǒng),簡單說圖表配置比較方便、生成的圖表比較漂亮。下面就介紹了利用Prometheus與Grafana對Mysql服務(wù)器性能監(jiān)控的方法。
    2017-03-03
  • mysql通配符的具體使用

    mysql通配符的具體使用

    通配符用于替換字符串中的一個(gè)或多個(gè)字符,通配符與LIKE運(yùn)算符一起使用,本文就詳細(xì)的介紹了mysql通配符的使用,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-05-05

最新評論