走進元數據不一致系列(一)——Catalog is missing n attribute(s) for relid xxx

      網友投稿 1852 2025-03-31

      前言

      元數據不一致問題往往會導致業務上的報錯,在現網環境中,“元數據不一致”一詞常常讓客戶、一線、二線甚至研發兄弟們談虎色變,但是很多人其實并不清楚“元數據不一致”到底是什么,該如何處理。元數據不一致真的有那么可怕嗎?接下來本文將以一種常見的元數據不一致場景為例,帶領讀者揭開元數據不一致的神秘面紗

      聲明

      1.此系列博文的初衷是構建更加強大的生態社區,提升大家對GaussDB(DWS)的認識,在現網運維過程中減少工具人的角色,因此只講解元數據不一致的原理和應急方法,不討論“是否為產品質量問題”等敏感話題

      2.此系列博文所有數據內容均為實驗環境構造,非客戶數據,不涉及客戶隱私

      3.此系列屬于技術原理類博文,不建議客戶、一線、二線在讀完此系列之后直接處理生產環境的元數據不一致問題

      什么是元數據不一致

      在執行DDL操作時,會將表的元信息記錄在系統表中,例如,執行一個簡單的create table test(a int,b int)操作,會在pg_class中新增一條數據來記錄表信息,在pg_type中新增一條數據來記錄與這張表對應的存儲數據類型,在pg_depend中新增一條數據來記錄pg_class中的數據和pg_type中的數據之間的依賴關系,在pg_attribute中新增九條數據來記錄字段a、字段b以及表的7個默認隱藏字段。

      當系統表之間的信息不匹配時,就出現了元數據不一致的場景,例如,當pg_class中記錄還在,而pg_attribute中對應記錄不存在時,訪問該表就會報錯。

      常見的系統表之間依賴關系如下圖

      一種經典問題場景

      元數據不一致的場景有很多,這里我們先看一種比較經典的場景:Catalog is missing n attribute(s) for relid xxx

      (這里在測試環境上已經構造好了問題場景,構造方法會附在博文最后)

      測試環境:3節點,每個節點1個cn,4個主dn

      集群拓撲:

      問題現象:在cn5001上查詢select * from public.testmissingattr時報錯:dn_6001_6002: Catalog is missing 2 attribute(s) for relid 62439689

      問題分析:

      1.首先分析報錯信息,Catalog is missing n attribute(s) for relid xxx的直接報錯原因,是pg_class中該表的relnatts字段與pg_attribute中該表非隱藏列的記錄數不匹配

      pg_attribute中attnum大于0的記錄表示非隱藏列

      2.根據報錯信息中的detail,我們可以確定在dn6001上,pg_class中該表的relnatts字段值為4,而pg_attribute中缺少了attnum為1和3的字段記錄;該表在dn6001上pg_class中的oid為62439689

      3.到dn6001上確認問題現象(如何連接某個dn不在此贅述)

      select oid,* from pg_class where oid = 62439689;

      可以看到在pg_class中relnatts的值確實是4

      select * from pg_attribute where attrelid = 62439689;

      可以看到pg_attribute中確實缺少了attnum為1和3的列

      注意,當發生元數據不一致時,一定要先判斷不一致時到底哪一側是正確的,在此場景中就是要判斷是pg_class中的relnatts值記錄錯誤,還是pg_attribute中記錄缺失

      判斷的依據,往往是根據cn或其他正常未報錯的dn來判斷,或從業務側進行判斷

      (由于pg_attribute中一張表的attnum一定是連續的,因此根據上圖可以快速判斷是pg_attribute中缺少記錄,但是如果上圖存在的兩條記錄attnum為1,2而不是2,4,就要根據其他cn或dn的表定義來進行判斷)

      在cn查看表定義,確認是4個字段,pg_class中記錄正確,pg_attribute中缺失字段a和c

      3.由于系統表的查詢都是優先從syscache中掃描,而syscache都是帶索引掃描,因此我們需要將索引關掉,再查詢一遍,來確認是僅有索引中缺少這兩條記錄,還是pg_attribute中確實缺少這兩條記錄。

      關閉索引再次查詢:

      start transaction read only;

      set enable_indexscan=off;

      set enable_bitmapscan=off;

      explain select * from pg_attribute where attrelid = 62439689;

      確認執行計劃是走seq scan之后,再次查詢

      select * from pg_attribute where attrelid = 62439689;

      rollback;

      再次查詢的結果,可以分為兩種情況討論:

      走進元數據不一致系列(一)——Catalog is missing n attribute(s) for relid xxx

      關閉索引后,查詢正常

      這說明數據本身沒有缺失,只是索引文件中缺失了,因此只要重建索引即可修復

      在dn上對系統表重建索引:

      start transaction read write;

      reindex table pg_attribute;

      commit;

      需要注意的是,在cn上不能直接對系統表重建索引,會報錯cannot PREPARE a transaction that modified relation mapping,因此如果是cn上需要重建系統表的索引,就要對系統表做vacuum full進行修復

      vacuum full pg_attribute;

      關閉索引后,查詢結果不變

      這說明是pg_attribute中確實缺少了記錄,此時我們優先查到對應的備dn(在此案例中為6002)是否正常,如果備dn正常,則停止集群,從備dn拷貝對應文件到主dn

      如何找到表的對應文件,不在這里贅述,可參考博文:GaussDB(DWS)磁盤使用率相關問題定位指南https://bbs.huaweicloud.com/blogs/174806

      如果備dn與主dn查詢結果一致,則需要手動恢復一致性,此場景一般根據正常cn或dn的pg_attribute記錄,將缺失的記錄在dn6001補齊

      恢復步驟:

      a.在正常的cn或dn查詢該表在pg_attribute中attnum為1和3的字段

      在cn5001執行:

      select oid,* from pg_class where relname = 'testmissingattr' and relnamespace = (select oid from pg_namespace where nspname = 'public'); #同一張表在不同的cn和dn上oid都是不一樣的,要重新查詢

      select * from pg_attribute where attrelid = 574785;

      查到缺失的兩條記錄,根據此信息在dn6001上補齊

      在dn6001執行

      start transaction read write;

      insert into pg_attribute values (62439689,'a',23,-1,4,1,0,-1,-1,'t','p','i','f','f','f','t',127,0,0,NULL,NULL,NULL,NULL);

      insert into pg_attribute values (62439689,'c',23,-1,4,3,0,-1,-1,'t','p','i','f','f','f','t',127,0,0,NULL,NULL,NULL,NULL);

      select * from pg_attribute where attrelid = 62439689;

      確認已經補齊

      select * from public.testmissingattr limit 1;

      查詢該表不再報錯

      commit;

      提交事務使修復生效

      到這里,此場景已經修復完畢,表可以繼續正常使用

      注意事項:

      所有操作都放在事務中做,執行結果不符合預期之后及時回滾

      找對cn/dn

      系統表字段不要混淆

      總結

      本文以一個經典的元數據不一致場景為例,介紹了元數據不一致的原理、定位及修復,下期博文將繼續介紹元數據不一致的其他經典場景,幫助大家更好的理解元數據不一致現象

      附:場景構造

      在cn執行

      create table public.testmissingattr(a int,b int,c int,d int);

      在任一dn執行

      start transaction read write;

      delete from pg_attribute where attrelid = (select oid from pg_class where relname = 'testmissingattr' and relnamespace = (select oid from pg_namespace where nspname = 'public')) and attname = 'a';

      delete from pg_attribute where attrelid = (select oid from pg_class where relname = 'testmissingattr' and relnamespace = (select oid from pg_namespace where nspname = 'public')) and attname = 'c';

      commit;

      EI企業智能 Gauss AP 數據倉庫服務 GaussDB(DWS)

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:jpg格式文字可以轉換成word文檔嗎(word文檔轉為jpg格式)
      下一篇:怎么在表格里標題加色(怎么給表格標題加顏色)
      相關文章
      久久乐国产综合亚洲精品| 亚洲网站视频在线观看| 亚洲av永久中文无码精品| 亚洲国产成人精品女人久久久 | 亚洲熟妇av一区二区三区| 一级毛片直播亚洲| 亚洲激情视频在线观看| 亚洲AV无码乱码在线观看裸奔| 亚洲国产精品无码观看久久| 亚洲熟女乱色一区二区三区| 久久久久亚洲国产| 亚洲女子高潮不断爆白浆| 亚洲熟女综合色一区二区三区| 久久国产亚洲精品| 亚洲精品美女久久久久久久| 亚洲国产精品无码久久98| 人人狠狠综合久久亚洲| 亚洲av日韩av欧v在线天堂| 午夜亚洲乱码伦小说区69堂| 亚洲激情校园春色| 亚洲国产精品乱码在线观看97| 亚洲欧洲自拍拍偷午夜色| 亚洲国产成人综合| 国内精品久久久久影院亚洲 | 亚洲亚洲人成综合网络| 亚洲人成网77777亚洲色 | 亚洲综合国产成人丁香五月激情| 久久国产亚洲精品| 麻豆亚洲AV成人无码久久精品| 亚洲精品456在线播放| 亚洲剧情在线观看| 亚洲色最新高清av网站| 日本亚洲欧美色视频在线播放| 亚洲一区二区三区丝袜| 久久久久亚洲国产AV麻豆 | 亚洲国产精品成人久久| 久久久无码精品亚洲日韩蜜桃| 久久亚洲AV成人无码| 亚洲AV无码专区电影在线观看| 亚洲精选在线观看| 亚洲成无码人在线观看|