← ყველა სტატია

ONLINE_UNCERTAIN: როცა MySQL ოპერატორი და ბაზა ვერ თანხმდებიან

Router ციმციმებს, ოპერატორი ორი დღეა ბლოკირებაშია, CRD 2/3-ზე გაიყინა — თან InnoDB Cluster-ის სამივე წევრი ჯანმრთელია. გამოსავალი მეტამონაცემების ერთი rescan იყო.

Optimacros-ში სამკვანძიანი MySQL InnoDB Cluster, რომელსაც Oracle MySQL Operator მართავს, კომპანიის მარკეტინგულ საიტებს ემსახურება. ერთ დილას სიმპტომების ჯაჭვი ოთხ ფენად აღმოჩნდა და ყოველი ფენა სხვა მიმართულებით მიუთითებდა.

დაიწყო ფრაზით „router OOM-ით ეცემა“. შემდეგ MySQL Router-ის პოდები Error-ში გადაიტვირთებოდნენ. შემდეგ „ბაზა დეგრადირდა“. კლასტერის custom resource აჩვენებდა ONLINE_UNCERTAIN-ს, სამიდან ორ ინსტანსს ონლაინ, ხოლო lastProbeTime ორი დღე არ განახლებულა. ოპერატორი ყოველ ორ წამში წერდა not ONLINE ერთ წევრზე და Cluster status results inconsistent.

ბაზას ჰკითხე და არა ოპერატორს

ბუნებრივი შემდეგი ნაბიჯი „მკვდარი“ წევრის თავიდან აწყობა იქნებოდა. ამის ნაცვლად Group Replication-ს პირდაპირ ვკითხე, read-only, primary-ზე:

SELECT member_host, member_state
FROM performance_schema.replication_group_members;

სამივე წევრი ONLINE იყო. ვითომ გაფუჭებული წევრი ჯგუფს incremental recovery-ით ჯერ კიდევ ორი დღით ადრე დაუბრუნდა. ბაზა ჯანმრთელი იყო. ჯანმრთელი არ იყო ოპერატორის სურათი.

რატომ ცრუობდა ოპერატორი

ამ წევრის datadir ცოტა ხნით ადრე თავიდან ააწყვეს, ხოლო თავიდან აწყობილი ან კლონირებული MySQL ინსტანსი ყოველთვის ახალ server_uuid-ს იღებს. Group Replication მას ახალი UUID-ით იცნობდა. კლასტერის მეტამონაცემების სქემა კი ჯერ კიდევ ძველს ინახავდა.

ოპერატორი Group Replication-ის წევრებს მეტამონაცემებს UUID-ით ადარებს. ის ძველ UUID-ს ეძებდა, ონლაინ ვერ პოულობდა, წევრს დაცემულად აცხადებდა და „შეუსაბამო“ სტატუსს აბრუნებდა. უფრო უარესი, მთელი ამ დროის განმავლობაში კლასტერის busy-lock ეჭირა: მისმა სტატუსის დამმუშავებელმა 27 000-ზე მეტი განმეორება გააკეთა ამ წევრის კუთვნილი ბლოკირებით, აქედან გაიყინა custom resource. თავად MySQL Shell-ის cluster.status() პირდაპირ ამბობდა: OK_PARTIAL და ინსტანსის შეცდომა მინიშნებით cluster.rescan().

Router იმიტომ ციმციმებდა, რომ ნაჩვენები ტოპოლოგია არასტაბილური ჩანდა. ზემოთ ყველა სიმპტომი ნამდვილი იყო, მაგრამ არც ერთი მიზეზი არ ყოფილა.

გამოსწორება

ჯერ მხოლოდ მეტამონაცემების სქემის ბექაპი mysqldump --single-transaction-ით. შემდეგ primary-დან:

dba.getCluster().rescan()

rescan() მეტამონაცემებს რეალობასთან შესაბამისობაში მოჰყავს: ჩაწერა წევრის ახალი UUID და წაშალა recovery-ის ობოლი ანგარიში. ის მეტამონაცემებს ეხება და არა აპლიკაციის მონაცემებს, და იდემპოტენტურია. ოპერატორმა მაშინვე შეთანხმებული სურათი მიიღო, ბლოკირება გაათავისუფლა და custom resource-ს ONLINE სამი ინსტანსით დაუბრუნა. ბლოკირება რომ შენარჩუნებულიყო, შემდეგი ნაბიჯი ოპერატორის Deployment-ის გადატვირთვა იქნებოდა.

რა არ უნდა გავაკეთოთ

ამაზე რამდენიმე დღით ადრე ამ კლასტერის წევრებს ნამდვილად ვაწყობდი თავიდან, ტომების ხელახლა შექმნით, რადგან მათი მონაცემები დაზიანებული იყო. ეს მოგონება თავიდან აწყობას აქაც მაცდურს ხდიდა. ეს შეცდომა იქნებოდა: წევრი უკვე ჯგუფში დაბრუნებული იყო, მოძველდა მხოლოდ აღრიცხვა. ჯანმრთელი წევრის თავიდან აწყობა რისკს მატებს და არაფერს ასწორებს.

რა უნდა დავიმახსოვროთ

  • InnoDB Cluster-ისთვის ჭეშმარიტება primary-ზე replication_group_members-ია. ოპერატორის .status აზრია, რომელიც შეიძლება გაიყინოს.
  • თავიდან აწყობილი ან კლონირებული წევრი ყოველთვის ახალ server_uuid-ს იღებს. cluster.rescan() წევრის ნებისმიერი აღდგენის სტანდარტული ბოლო ნაბიჯი გახადე.
  • გაყინული lastProbeTime და ათიათასობით განმეორების მთვლელი გაჭედილ კონტროლერს ნიშნავს და არა გაფუჭებულ ბაზას.
  • მეტამონაცემების სქემას შეხებამდე ბექაპი გაუკეთე, მაშინაც კი, როცა ოპერაცია უსაფრთხოდ არის დოკუმენტირებული.