欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Mysql大表全表update的的實(shí)現(xiàn)

 更新時(shí)間:2024年08月20日 10:07:00   作者:最愛彩虹糖  
有些時(shí)候在進(jìn)行一些業(yè)務(wù)迭代時(shí)需要我們對(duì)Mysql表中數(shù)據(jù)進(jìn)行全表update,本文主要介紹了Mysql大表update的的實(shí)現(xiàn)

前言

有些時(shí)候在進(jìn)行一些業(yè)務(wù)迭代時(shí)需要我們對(duì)Mysql表中數(shù)據(jù)進(jìn)行全表update,如果是在數(shù)據(jù)量比較小的情況下(萬級(jí)別),可以直接執(zhí)行sql語句,但是如果數(shù)據(jù)量達(dá)到一個(gè)量級(jí)后,就會(huì)出現(xiàn)一些問題,比如主從架構(gòu)部署的Mysql,主從同步需要需要binlog來完成,而binlog格式如下,其中使用statement和row格式的主從同步之間binlog在update情況下的展示:

格式內(nèi)容
statement記錄同步在主庫上執(zhí)行的每一條sql,日志量較少,減少io,但是部分函數(shù)sql會(huì)出現(xiàn)問題比如random
row記錄每一條數(shù)據(jù)被修改或者刪除的詳情,日志量在特定條件下很大,如批量delete、update
mixed以上兩種方式混用,一般的語句修改使用statement記錄,其他函數(shù)式使用row

在這里插入圖片描述

我們當(dāng)前線上mysql是使用row格式binlog來進(jìn)行的主從同步,因此如果在億級(jí)數(shù)據(jù)的表中執(zhí)行全表update,必然會(huì)在主庫中產(chǎn)生大量的binlog,接著會(huì)在進(jìn)行主從同步時(shí),從庫也需要阻塞執(zhí)行大量sql,風(fēng)險(xiǎn)極高,因此直接update是不行的。本文就從我最開始的一個(gè)全表update sql開始,到最后上線的分批更新策略,如何優(yōu)化和思考來展開說明。

正文

直接update的問題

我們前段時(shí)間需要將用戶的一些基本信息存儲(chǔ)從http轉(zhuǎn)換為https,庫中數(shù)據(jù)大概在幾千w的級(jí)別,需要對(duì)一些大表進(jìn)行全表update,最開始我試探性的跟dba同事拋出了一個(gè)簡(jiǎn)單的update語句,想著流量低的時(shí)候執(zhí)行,如下:

update tb_user_info set user_img=replace(user_img,'http://','https://')

深度分頁問題

上面肯定是不合理的會(huì)給主庫生成binlog、從庫接收binlog寫數(shù)據(jù)帶來很大的壓力,于是就想使用腳本分批處理如下所示: 寫一個(gè)這樣的腳本,依次分批替換,limit的游標(biāo)不斷增加。大概一看是沒有問題的,但是仔細(xì)一想mysql的limit游標(biāo)進(jìn)行的范圍查找原理,是下沉到B+數(shù)的葉子節(jié)點(diǎn)進(jìn)行的向后遍歷查找,在limit數(shù)據(jù)比較小的情況下還好,limit數(shù)據(jù)量比較大的情況下,效率很低接近于全表掃描,這也就是我們常說的“深度分頁問題”。

update tb_user_info set user_img=replace(user_img,'http://','https://') limit 1,1000;

in的效率

既然mysql的深分頁有問題,那么我就把這批id全部查出來,然后更新的id in這些列表,進(jìn)行批量更新可以嗎?于是我又寫了類似下面sql的腳本。結(jié)果是還不行,雖然mysql對(duì)于in這些查找有一些鍵值預(yù)測(cè),但是仍然是很低效。

select * from tb_user_info where id> {index} limit 100;
update tb_user_info set user_img=replace(user_img,'http','https')where id in {id1,id3,id2};

最終版本

最終在與dba的多次溝通下,我們寫了如下的sql及腳本,這里有幾個(gè)問題需要注意,我們?cè)趕elect sql中使用了這個(gè)語法/*!40001 SQL_NO_CACHE */,這個(gè)語法的意思就是本次查詢不使用innodb的buffer pool,也不會(huì)將本次查詢的數(shù)據(jù)頁放到buffer pool中作為熱點(diǎn)數(shù)據(jù)的緩存。接著對(duì)于查詢強(qiáng)制使用主鍵索引FORCE INDEX(PRIMARY),并且根據(jù)主鍵索引排序,排序后的數(shù)據(jù)進(jìn)行id游標(biāo)的篩選。最后執(zhí)行update更新時(shí),由于我們?cè)谇懊娴膕ql中查詢到的就是已經(jīng)排序后的主鍵,因此可以對(duì)id執(zhí)行范圍查找。

select /*!40001 SQL_NO_CACHE */ id from tb_user_info FORCE INDEX(`PRIMARY`) where id> "1" ORDER BY id limit 1000,1;
update tb_user_info set user_img=replace(user_img,'http','https') where id >"{1}" and id <"{2}";

我們可以僅關(guān)注第一個(gè)sql,如下圖所示,是buffer pool大概內(nèi)容,我們可以通過這個(gè)no cache的關(guān)鍵字,對(duì)批量處理的數(shù)據(jù)進(jìn)行強(qiáng)制指定不走buffer pool,不把這些冷數(shù)據(jù)影響到正常使用的緩存內(nèi)容,防止效率的降低,其實(shí)mysql在一些備份的動(dòng)作中。使用的數(shù)據(jù)掃描sql也會(huì)帶上這個(gè)關(guān)鍵字,防止影響到正常的業(yè)務(wù)緩存;接著需要強(qiáng)制對(duì)當(dāng)前查詢指定的主鍵索引,然后進(jìn)行排序,否則mysql有可能在計(jì)算io成本進(jìn)行索引選擇時(shí),選擇其他的索引。

在這里插入圖片描述

使用這樣的方式對(duì)數(shù)據(jù)庫進(jìn)行批量更新可以通過一個(gè)接口來控制速率,對(duì)于數(shù)據(jù)庫主從同步、iops、內(nèi)存使用率等關(guān)鍵屬性進(jìn)行觀察,手動(dòng)調(diào)整刷庫速率。這樣看是單線程阻塞的操作,其實(shí)接口也可以定義線程個(gè)數(shù)等屬性,接口中根據(jù)賦予的線程個(gè)數(shù),通過線程池并行刷數(shù)據(jù),從而提高全表更新速率的上限,同時(shí)對(duì)速率進(jìn)行控制控制。

其他問題

如果我們使用snowflake雪花算法或者自增主鍵來生成主鍵id的話,插入的記錄都是根據(jù)主鍵id順序插入的,如果使用uuid這種我們?cè)趺刺幚???dāng)然是業(yè)務(wù)中就預(yù)先處理了,先把入庫的數(shù)據(jù)提前進(jìn)行替換,進(jìn)行代碼上線后再進(jìn)行的全量數(shù)據(jù)更新了。

結(jié)語

刷數(shù)據(jù)本來是一個(gè)異??菰锏墓ぷ鲀?nèi)容,但是從這次數(shù)據(jù)量較大的數(shù)據(jù)更新從而與dba同事的多次溝通后,也對(duì)mysql有了一些新的理解,包括不限于下面幾個(gè),共同學(xué)習(xí)。

  • binlog格式帶來的大數(shù)據(jù)量更新的主從同步問題;
  • Mysql深分頁的效率問題;
  • 全表掃數(shù)據(jù)如何防止對(duì)buffer pool污染到我們業(yè)務(wù)正常的熱點(diǎn)數(shù)據(jù)。

到此這篇關(guān)于Mysql大表update的的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)Mysql大表update內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家! 

相關(guān)文章

  • MySQL 中處理 BLOB 和 CLOB 數(shù)據(jù)類型小結(jié)

    MySQL 中處理 BLOB 和 CLOB 數(shù)據(jù)類型小結(jié)

    在MySQL中,BLOB和CLOB 數(shù)據(jù)類型用于存儲(chǔ)大量的二進(jìn)制數(shù)據(jù)和字符數(shù)據(jù),可以使用SQL 語句或編程語言將二進(jìn)制數(shù)據(jù)和字符數(shù)據(jù)插入到BLOB 和CLOB列中,這篇文章主要介紹了MySQL 中處理 BLOB 和 CLOB 數(shù)據(jù)類型,需要的朋友可以參考下
    2025-03-03
  • mysql免安裝制作使用說明

    mysql免安裝制作使用說明

    mysql免安裝版本的制作方法,需要的朋友可以參考下。
    2010-08-08
  • 解決mysql導(dǎo)入還原時(shí)亂碼的問題

    解決mysql導(dǎo)入還原時(shí)亂碼的問題

    sql文件,直接記事本方式打開,中文顯示正常,還原導(dǎo)入后,發(fā)現(xiàn)中文是亂碼
    2012-12-12
  • mysql 數(shù)據(jù)插入優(yōu)化方法

    mysql 數(shù)據(jù)插入優(yōu)化方法

    當(dāng)一個(gè)線程對(duì)一個(gè)表執(zhí)行一個(gè)DELAYED語句時(shí),如果不存在這樣的處理程序,一個(gè)處理器線程被創(chuàng)建以處理對(duì)于該表的所有DELAYED語句。
    2010-12-12
  • mysql 有關(guān)“InnoDB Error ib_logfile0 of different size”錯(cuò)誤

    mysql 有關(guān)“InnoDB Error ib_logfile0 of different size”錯(cuò)誤

    mysql 有關(guān)“InnoDB Error ib_logfile0 of different size”錯(cuò)誤的解決方法,需要的朋友可以參考下。
    2011-06-06
  • MySQL讀寫分離服務(wù)配置方式

    MySQL讀寫分離服務(wù)配置方式

    通過Mycat代理實(shí)現(xiàn)MySQL的讀寫分離涉及準(zhǔn)備工作、配置文件修改、權(quán)限設(shè)置、啟動(dòng)方式選擇等關(guān)鍵步驟,首先,安裝JDK1.8并配置環(huán)境變量;接著,對(duì)Mycat的server.xml和schema.xml進(jìn)行配置,特別是schema.xml中對(duì)數(shù)據(jù)庫的配置需關(guān)注
    2024-11-11
  • JDBC-idea導(dǎo)入mysql連接java的jar包(mac)的方法

    JDBC-idea導(dǎo)入mysql連接java的jar包(mac)的方法

    這篇文章主要介紹了JDBC-idea導(dǎo)入mysql連接java的jar包(mac)的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-09-09
  • MySQL中使用CTE獲取時(shí)間段數(shù)據(jù)的技巧分享

    MySQL中使用CTE獲取時(shí)間段數(shù)據(jù)的技巧分享

    在數(shù)據(jù)庫操作中,獲取特定時(shí)間段的數(shù)據(jù)是一項(xiàng)常見任務(wù),MySQL自從8.0版本開始支持CTE(公共表表達(dá)式),使得我們可以更加靈活和高效地處理時(shí)間段數(shù)據(jù),本文小編介紹了MySQL中使用CTE獲取時(shí)間段數(shù)據(jù)的技巧分享,需要的朋友可以參考下
    2024-08-08
  • MySQL數(shù)據(jù)庫十大優(yōu)化技巧

    MySQL數(shù)據(jù)庫十大優(yōu)化技巧

    WEB開發(fā)者不光要解決程序的效率問題,對(duì)數(shù)據(jù)庫的快速訪問和相應(yīng)也是一個(gè)大問題。希望本文能對(duì)大家掌握MySQL優(yōu)化技巧有所幫助。
    2011-03-03
  • MySQL創(chuàng)建、修改和刪除表操作指南

    MySQL創(chuàng)建、修改和刪除表操作指南

    MySQL是最常用的數(shù)據(jù)庫,在數(shù)據(jù)庫操作中,基本都是增刪改查操作,簡(jiǎn)稱CRUD,下面這篇文章主要給大家介紹了關(guān)于MySQL創(chuàng)建、修改和刪除表的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-08-08

最新評(píng)論