[{"data":1,"prerenderedAt":957},["ShallowReactive",2],{"content:\u002F2026\u002F03\u002Fgh-ost-migrate-mysql-online":3,"surround:\u002F2026\u002F03\u002Fgh-ost-migrate-mysql-online":946},{"id":4,"title":5,"body":6,"categories":922,"date":924,"description":925,"draft":926,"extension":927,"image":928,"meta":929,"navigation":931,"path":932,"permalink":928,"published":928,"readingTime":933,"recommend":928,"references":928,"seo":938,"sitemap":939,"stem":940,"tags":941,"type":943,"updated":944,"__hash__":945},"content\u002Fposts\u002F2026\u002F03\u002Fgh-ost-migrate-mysql-online.md","千万级 Mysql 表结构变更实战",{"type":7,"value":8,"toc":908},"minimark",[9,22,38,41,44,52,56,65,75,85,91,100,106,127,133,136,157,164,198,222,225,228,308,311,314,386,389,449,452,512,515,575,579,637,640,904],[10,11,12,13,17,18,21],"p",{},"在生产环境中，对千万级数据表直接执行 ",[14,15,16],"code",{"code":16},"ALTER TABLE"," 进行结构修改，往往会导致表被锁定，从而阻塞写入操作，可能造成数据不一致或业务停顿。为了安全、无感知地变更大表结构，",[14,19,20],{"code":20},"gh-ost"," 提供了一种高效、零停机的解决方案。",[10,23,24,25,29,30,33,34,37],{},"它通过创建",[26,27,28],"strong",{},"镜像表","、",[26,31,32],{},"全量+增量同步数据","，最终使用",[26,35,36],{},"原子级别的表重命名切换","完成变更。整个过程可以随时暂停，对业务几乎无影响，非常适合 500 万条以上的大表操作。",[39,40,20],"h2",{"id":20},[10,42,43],{},"生产环境最常用, 适用于 500 万条数据以上",[10,45,46],{},[47,48,49],"a",{"href":49,"rel":50},"https:\u002F\u002Fgithub.com\u002Fgithub\u002Fgh-ost",[51],"nofollow",[53,54,55],"h3",{"id":55},"工作原理",[57,58,59],"ol",{},[60,61,62,63],"li",{},"创建",[26,64,28],{},[66,67,73],"pre",{"className":68,"code":70,"language":71,"meta":72},[69],"language-text","t_dir_gho\n","text","",[14,74,70],{"__ignoreMap":72},[57,76,78],{"start":77},2,[60,79,80,81,84],{},"同步原表数据(",[14,82,83],{"code":83},"t_dir",")",[66,86,89],{"className":87,"code":88,"language":71,"meta":72},[69],"copy data\n",[14,90,88],{"__ignoreMap":72},[57,92,94],{"start":93},3,[60,95,96,99],{},[14,97,98],{"code":98},"binlog"," 增量同步",[66,101,104],{"className":102,"code":103,"language":71,"meta":72},[69],"实时同步变更\n",[14,105,103],{"__ignoreMap":72},[57,107,109],{"start":108},4,[60,110,111,112,115,116,118,119,115,122,118,125],{},"最终 ",[26,113,114],{},"原子切换",", 将 ",[14,117,83],{"code":83}," 重命名为 ",[14,120,121],{"code":121},"t_dir_old",[14,123,124],{"code":124},"t_dir_gho",[14,126,83],{"code":83},[66,128,131],{"className":129,"code":130,"language":71,"meta":72},[69],"rename table\n",[14,132,130],{"__ignoreMap":72},[10,134,135],{},"优点：",[137,138,139,142,151,154],"ul",{},[60,140,141],{},"rename 表是原子操作",[60,143,144,147,148,150],{},[26,145,146],{},"不停写,"," 因为是镜像表的缘故,除了全量同步,同时通过 ",[14,149,98],{"code":98}," 订阅原表对镜像表进行增量同步",[60,152,153],{},"可随时暂停",[60,155,156],{},"对业务无感",[10,158,159,160,163],{},"实际上在表切换的过程中,执行的以下 ",[14,161,162],{"code":162},"Sql"," 语句",[66,165,169],{"className":166,"code":167,"language":168,"meta":72,"style":72},"language-sql shiki shiki-themes github-light github-dark","RENAME TABLE t_dir TO t_dir_old,t_dir_new TO t_dir;\n","sql",[14,170,171],{"__ignoreMap":72},[172,173,176,180,184,187,190,193,195],"span",{"class":174,"data-line":175,"line":175},"line",1,[172,177,179],{"class":178},"sVt8B","RENAME ",[172,181,183],{"class":182},"szBVR","TABLE",[172,185,186],{"class":178}," t_dir ",[172,188,189],{"class":182},"TO",[172,191,192],{"class":178}," t_dir_old,t_dir_new ",[172,194,189],{"class":182},[172,196,197],{"class":178}," t_dir;\n",[10,199,200,201,204,205,208,209,212,213,215,216,218,219,221],{},"切换的时间",[14,202,203],{"code":203},"\u003C 1ms",",在这 ",[14,206,207],{"code":207},"1ms","中 ",[14,210,211],{"code":211},"Rename","会锁表,假如说这一瞬间对原表(",[14,214,83],{"code":83},")进行写操作,那么会短暂停顿等待切换后的\"",[14,217,83],{"code":83},"\"释放锁, 所以并不会造成数据丢失, 而且这",[14,220,207],{"code":207},"很短,对业务无感",[39,223,224],{"id":224},"常见使用示例",[53,226,227],{"id":227},"添加索引",[66,229,233],{"className":230,"code":231,"language":232,"meta":72,"style":72},"language-bash shiki shiki-themes github-light github-dark","gh-ost \\\n--host=127.0.0.1 \\\n--user=root \\\n--password=123456 \\\n--database=db \\\n--table=t_dir \\\n--alter=\"ADD INDEX idx_uid(uid)\" \\\n--allow-on-master \\\n--execute\n","bash",[14,234,235,244,252,259,266,274,282,294,302],{"__ignoreMap":72},[172,236,237,240],{"class":174,"data-line":175,"line":175},[172,238,20],{"class":239},"sScJk",[172,241,243],{"class":242},"sj4cs"," \\\n",[172,245,246,249],{"class":174,"data-line":77,"line":77},[172,247,248],{"class":178},"--host=127.0.0.1 ",[172,250,251],{"class":242},"\\\n",[172,253,254,257],{"class":174,"data-line":93,"line":93},[172,255,256],{"class":178},"--user=root ",[172,258,251],{"class":242},[172,260,261,264],{"class":174,"data-line":108,"line":108},[172,262,263],{"class":178},"--password=123456 ",[172,265,251],{"class":242},[172,267,269,272],{"class":174,"data-line":268,"line":268},5,[172,270,271],{"class":178},"--database=db ",[172,273,251],{"class":242},[172,275,277,280],{"class":174,"data-line":276,"line":276},6,[172,278,279],{"class":178},"--table=t_dir ",[172,281,251],{"class":242},[172,283,285,288,292],{"class":174,"data-line":284,"line":284},7,[172,286,287],{"class":178},"--alter=",[172,289,291],{"class":290},"sZZnC","\"ADD INDEX idx_uid(uid)\"",[172,293,243],{"class":242},[172,295,297,300],{"class":174,"data-line":296,"line":296},8,[172,298,299],{"class":178},"--allow-on-master ",[172,301,251],{"class":242},[172,303,305],{"class":174,"data-line":304,"line":304},9,[172,306,307],{"class":178},"--execute\n",[53,309,310],{"id":310},"修改字段类型",[10,312,313],{},"例如：",[66,315,317],{"className":230,"code":316,"language":232,"meta":72,"style":72},"INT → BIGINT\ngh-ost \\\n--host=127.0.0.1 \\\n--user=root \\\n--password=123456 \\\n--database=db \\\n--table=t_dir \\\n--alter=\"MODIFY COLUMN uid BIGINT\" \\\n--allow-on-master \\\n--execute\n",[14,318,319,330,336,342,348,354,360,366,375,381],{"__ignoreMap":72},[172,320,321,324,327],{"class":174,"data-line":175,"line":175},[172,322,323],{"class":239},"INT",[172,325,326],{"class":290}," →",[172,328,329],{"class":290}," BIGINT\n",[172,331,332,334],{"class":174,"data-line":77,"line":77},[172,333,20],{"class":239},[172,335,243],{"class":242},[172,337,338,340],{"class":174,"data-line":93,"line":93},[172,339,248],{"class":178},[172,341,251],{"class":242},[172,343,344,346],{"class":174,"data-line":108,"line":108},[172,345,256],{"class":178},[172,347,251],{"class":242},[172,349,350,352],{"class":174,"data-line":268,"line":268},[172,351,263],{"class":178},[172,353,251],{"class":242},[172,355,356,358],{"class":174,"data-line":276,"line":276},[172,357,271],{"class":178},[172,359,251],{"class":242},[172,361,362,364],{"class":174,"data-line":284,"line":284},[172,363,279],{"class":178},[172,365,251],{"class":242},[172,367,368,370,373],{"class":174,"data-line":296,"line":296},[172,369,287],{"class":178},[172,371,372],{"class":290},"\"MODIFY COLUMN uid BIGINT\"",[172,374,243],{"class":242},[172,376,377,379],{"class":174,"data-line":304,"line":304},[172,378,299],{"class":178},[172,380,251],{"class":242},[172,382,384],{"class":174,"data-line":383,"line":383},10,[172,385,307],{"class":178},[53,387,388],{"id":388},"添加字段",[66,390,392],{"className":230,"code":391,"language":232,"meta":72,"style":72},"gh-ost \\\n--host=127.0.0.1 \\\n--user=root \\\n--password=123456 \\\n--database=db \\\n--table=t_dir \\\n--alter=\"ADD COLUMN status INT NOT NULL DEFAULT 0\" \\\n--allow-on-master \\\n--execute\n",[14,393,394,400,406,412,418,424,430,439,445],{"__ignoreMap":72},[172,395,396,398],{"class":174,"data-line":175,"line":175},[172,397,20],{"class":239},[172,399,243],{"class":242},[172,401,402,404],{"class":174,"data-line":77,"line":77},[172,403,248],{"class":178},[172,405,251],{"class":242},[172,407,408,410],{"class":174,"data-line":93,"line":93},[172,409,256],{"class":178},[172,411,251],{"class":242},[172,413,414,416],{"class":174,"data-line":108,"line":108},[172,415,263],{"class":178},[172,417,251],{"class":242},[172,419,420,422],{"class":174,"data-line":268,"line":268},[172,421,271],{"class":178},[172,423,251],{"class":242},[172,425,426,428],{"class":174,"data-line":276,"line":276},[172,427,279],{"class":178},[172,429,251],{"class":242},[172,431,432,434,437],{"class":174,"data-line":284,"line":284},[172,433,287],{"class":178},[172,435,436],{"class":290},"\"ADD COLUMN status INT NOT NULL DEFAULT 0\"",[172,438,243],{"class":242},[172,440,441,443],{"class":174,"data-line":296,"line":296},[172,442,299],{"class":178},[172,444,251],{"class":242},[172,446,447],{"class":174,"data-line":304,"line":304},[172,448,307],{"class":178},[53,450,451],{"id":451},"删除字段",[66,453,455],{"className":230,"code":454,"language":232,"meta":72,"style":72},"gh-ost \\\n--host=127.0.0.1 \\\n--user=root \\\n--password=123456 \\\n--database=db \\\n--table=t_dir \\\n--alter=\"DROP COLUMN temp_field\" \\\n--allow-on-master \\\n--execute\n",[14,456,457,463,469,475,481,487,493,502,508],{"__ignoreMap":72},[172,458,459,461],{"class":174,"data-line":175,"line":175},[172,460,20],{"class":239},[172,462,243],{"class":242},[172,464,465,467],{"class":174,"data-line":77,"line":77},[172,466,248],{"class":178},[172,468,251],{"class":242},[172,470,471,473],{"class":174,"data-line":93,"line":93},[172,472,256],{"class":178},[172,474,251],{"class":242},[172,476,477,479],{"class":174,"data-line":108,"line":108},[172,478,263],{"class":178},[172,480,251],{"class":242},[172,482,483,485],{"class":174,"data-line":268,"line":268},[172,484,271],{"class":178},[172,486,251],{"class":242},[172,488,489,491],{"class":174,"data-line":276,"line":276},[172,490,279],{"class":178},[172,492,251],{"class":242},[172,494,495,497,500],{"class":174,"data-line":284,"line":284},[172,496,287],{"class":178},[172,498,499],{"class":290},"\"DROP COLUMN temp_field\"",[172,501,243],{"class":242},[172,503,504,506],{"class":174,"data-line":296,"line":296},[172,505,299],{"class":178},[172,507,251],{"class":242},[172,509,510],{"class":174,"data-line":304,"line":304},[172,511,307],{"class":178},[53,513,514],{"id":514},"重命名字段",[66,516,518],{"className":230,"code":517,"language":232,"meta":72,"style":72},"gh-ost \\\n--host=127.0.0.1 \\\n--user=root \\\n--password=123456 \\\n--database=db \\\n--table=t_dir \\\n--alter=\"CHANGE old_name new_name VARCHAR(255)\" \\\n--allow-on-master \\\n--execute\n",[14,519,520,526,532,538,544,550,556,565,571],{"__ignoreMap":72},[172,521,522,524],{"class":174,"data-line":175,"line":175},[172,523,20],{"class":239},[172,525,243],{"class":242},[172,527,528,530],{"class":174,"data-line":77,"line":77},[172,529,248],{"class":178},[172,531,251],{"class":242},[172,533,534,536],{"class":174,"data-line":93,"line":93},[172,535,256],{"class":178},[172,537,251],{"class":242},[172,539,540,542],{"class":174,"data-line":108,"line":108},[172,541,263],{"class":178},[172,543,251],{"class":242},[172,545,546,548],{"class":174,"data-line":268,"line":268},[172,547,271],{"class":178},[172,549,251],{"class":242},[172,551,552,554],{"class":174,"data-line":276,"line":276},[172,553,279],{"class":178},[172,555,251],{"class":242},[172,557,558,560,563],{"class":174,"data-line":284,"line":284},[172,559,287],{"class":178},[172,561,562],{"class":290},"\"CHANGE old_name new_name VARCHAR(255)\"",[172,564,243],{"class":242},[172,566,567,569],{"class":174,"data-line":296,"line":296},[172,568,299],{"class":178},[172,570,251],{"class":242},[172,572,573],{"class":174,"data-line":304,"line":304},[172,574,307],{"class":178},[53,576,578],{"id":577},"添加-not-null-字段","添加 NOT NULL 字段",[66,580,581],{"className":230,"code":391,"language":232,"meta":72,"style":72},[14,582,583,589,595,601,607,613,619,627,633],{"__ignoreMap":72},[172,584,585,587],{"class":174,"data-line":175,"line":175},[172,586,20],{"class":239},[172,588,243],{"class":242},[172,590,591,593],{"class":174,"data-line":77,"line":77},[172,592,248],{"class":178},[172,594,251],{"class":242},[172,596,597,599],{"class":174,"data-line":93,"line":93},[172,598,256],{"class":178},[172,600,251],{"class":242},[172,602,603,605],{"class":174,"data-line":108,"line":108},[172,604,263],{"class":178},[172,606,251],{"class":242},[172,608,609,611],{"class":174,"data-line":268,"line":268},[172,610,271],{"class":178},[172,612,251],{"class":242},[172,614,615,617],{"class":174,"data-line":276,"line":276},[172,616,279],{"class":178},[172,618,251],{"class":242},[172,620,621,623,625],{"class":174,"data-line":284,"line":284},[172,622,287],{"class":178},[172,624,436],{"class":290},[172,626,243],{"class":242},[172,628,629,631],{"class":174,"data-line":296,"line":296},[172,630,299],{"class":178},[172,632,251],{"class":242},[172,634,635],{"class":174,"data-line":304,"line":304},[172,636,307],{"class":178},[53,638,639],{"id":639},"常用参数说明",[641,642,643,659],"table",{},[644,645,646],"thead",{},[647,648,649,653,656],"tr",{},[650,651,652],"th",{},"参数",[650,654,655],{},"说明",[650,657,658],{},"示例",[660,661,662,678,693,708,723,738,752,767,780,793,808,823,838,853,866,878,891],"tbody",{},[647,663,664,670,673],{},[665,666,667],"td",{},[14,668,669],{"code":669},"--host",[665,671,672],{},"MySQL 地址",[665,674,675],{},[14,676,677],{"code":677},"127.0.0.1",[647,679,680,685,688],{},[665,681,682],{},[14,683,684],{"code":684},"--port",[665,686,687],{},"MySQL 端口",[665,689,690],{},[14,691,692],{"code":692},"3306",[647,694,695,700,703],{},[665,696,697],{},[14,698,699],{"code":699},"--user",[665,701,702],{},"数据库用户名",[665,704,705],{},[14,706,707],{"code":707},"root",[647,709,710,715,718],{},[665,711,712],{},[14,713,714],{"code":714},"--password",[665,716,717],{},"数据库密码",[665,719,720],{},[14,721,722],{"code":722},"123456",[647,724,725,730,733],{},[665,726,727],{},[14,728,729],{"code":729},"--database",[665,731,732],{},"目标数据库",[665,734,735],{},[14,736,737],{"code":737},"db",[647,739,740,745,748],{},[665,741,742],{},[14,743,744],{"code":744},"--table",[665,746,747],{},"目标表",[665,749,750],{},[14,751,83],{"code":83},[647,753,754,759,762],{},[665,755,756],{},[14,757,758],{"code":758},"--alter",[665,760,761],{},"要执行的 DDL",[665,763,764],{},[14,765,766],{"code":766},"ADD COLUMN size BIGINT",[647,768,769,774,777],{},[665,770,771],{},[14,772,773],{"code":773},"--execute",[665,775,776],{},"真正执行变更",[665,778,779],{},"不加则为 dry-run",[647,781,782,787,790],{},[665,783,784],{},[14,785,786],{"code":786},"--allow-on-master",[665,788,789],{},"允许在主库执行",[665,791,792],{},"常用",[647,794,795,800,803],{},[665,796,797],{},[14,798,799],{"code":799},"--chunk-size",[665,801,802],{},"每批迁移行数",[665,804,805],{},[14,806,807],{"code":807},"1000",[647,809,810,815,818],{},[665,811,812],{},[14,813,814],{"code":814},"--max-load",[665,816,817],{},"负载阈值",[665,819,820],{},[14,821,822],{"code":822},"Threads_running=20",[647,824,825,830,833],{},[665,826,827],{},[14,828,829],{"code":829},"--critical-load",[665,831,832],{},"临界负载",[665,834,835],{},[14,836,837],{"code":837},"Threads_running=100",[647,839,840,845,848],{},[665,841,842],{},[14,843,844],{"code":844},"--cut-over",[665,846,847],{},"切换策略",[665,849,850],{},[14,851,852],{"code":852},"default",[647,854,855,860,863],{},[665,856,857],{},[14,858,859],{"code":859},"--initially-drop-ghost-table",[665,861,862],{},"若存在 ghost 表先删除",[665,864,865],{},"安全",[647,867,868,873,876],{},[665,869,870],{},[14,871,872],{"code":872},"--initially-drop-old-table",[665,874,875],{},"若存在 old 表先删除",[665,877,865],{},[647,879,880,885,888],{},[665,881,882],{},[14,883,884],{"code":884},"--exact-rowcount",[665,886,887],{},"精确统计行数",[665,889,890],{},"避免误差",[647,892,893,898,901],{},[665,894,895],{},[14,896,897],{"code":897},"--verbose",[665,899,900],{},"输出详细日志",[665,902,903],{},"调试用",[905,906,907],"style",{},"html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}",{"title":72,"searchDepth":108,"depth":108,"links":909},[910,913],{"id":20,"depth":77,"text":20,"children":911},[912],{"id":55,"depth":93,"text":55},{"id":224,"depth":77,"text":224,"children":914},[915,916,917,918,919,920,921],{"id":227,"depth":93,"text":227},{"id":310,"depth":93,"text":310},{"id":388,"depth":93,"text":388},{"id":451,"depth":93,"text":451},{"id":514,"depth":93,"text":514},{"id":577,"depth":93,"text":578},{"id":639,"depth":93,"text":639},[923],"数据库","2026-03-10","利用 gh-ost 安全、实时地迁移数据，实现大表结构变更，无停机、无锁表。",false,"md",null,{"slots":930},{},true,"\u002F2026\u002F03\u002Fgh-ost-migrate-mysql-online",{"text":934,"minutes":935,"time":936,"words":937},"4 min read",3.215,192900,643,{"title":5,"description":925},{"loc":932},"posts\u002F2026\u002F03\u002Fgh-ost-migrate-mysql-online",[942],"mysql","tech","2026-05-06","SbFExn7PaX4_30Go-s3Y_2JfPs0dANl_iV_l4Xp560U",[947,952],{"title":948,"path":949,"stem":950,"date":951,"type":943,"children":-1},"MySQL 主从复制搭建与配置","\u002F2026\u002F02\u002Fmysql-master-slave-copy","posts\u002F2026\u002F02\u002Fmysql-master-slave-copy","2026-02-27",{"title":953,"path":954,"stem":955,"date":956,"type":943,"children":-1},"Kratos 配置管理实践","\u002F2026\u002F04\u002Fkratos-config","posts\u002F2026\u002F04\u002Fkratos-config","2026-04-12",1786555054299]