Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Utwórz indeks na ogromnej tabeli produkcyjnej MySQL bez blokowania tabeli

Aktualizacja [2017]:MySQL 5.6 obsługuje aktualizacje indeksu online

https://dev.mysql.com/doc/refman/8.0/en/innodb-online-ddl-operations.html#online-ddl-index-syntax-notes

W MySQL 5.6 i nowszych tabela pozostaje dostępna dla operacji odczytu i zapisu podczas tworzenia lub usuwania indeksu. Instrukcja CREATE INDEX lub DROP INDEX kończy się dopiero po zakończeniu wszystkich transakcji uzyskujących dostęp do tabeli, tak aby stan początkowy indeksu odzwierciedlał najnowszą zawartość tabeli. Wcześniej modyfikowanie tabeli podczas tworzenia lub usuwania indeksu zwykle powodowało zakleszczenie, które powodowało anulowanie instrukcji INSERT, UPDATE lub DELETE w tabeli.

[2015] Aktualizacja bloków indeksów tablicowych zapisów w MySQL 5.5

Z powyższej odpowiedzi:

„Jeśli korzystasz z wersji większej niż 5.1, indeksy są tworzone, gdy baza danych jest w trybie online. Więc nie martw się, nie przerwiesz korzystania z systemu produkcyjnego”.

To jest ****FAŁSZ**** (przynajmniej dla tabel MyISAM / InnoDB, z których korzysta 99,999% ludzi. Clustered Edition jest inny.)

Wykonanie operacji UPDATE na tabeli spowoduje ZABLOKOWANIE podczas tworzenia indeksu. MySQL jest naprawdę głupi w tej kwestii (i kilku innych rzeczach).

Skrypt testowy:

(   
  for n in {1..50}; do
    #(time mysql -uroot -e 'select  * from website_development.users where id = 41225\G'>/dev/null) 2>&1 | grep real;
    (time mysql -uroot -e 'update website_development.users set bio="" where id = 41225\G'>/dev/null) 2>&1 | grep real;
  done
) | cat -n &
PID=$!
sleep 0.05
echo "Index Update - START"
mysql -uroot website_development -e 'alter table users add index ddopsonfu (last_name, email, first_name, confirmation_token, current_sign_in_ip);'
echo "Index Update - FINISH"
sleep 0.05
kill $PID
time mysql -uroot website_development -e 'drop index ddopsonfu on users;'

Mój serwer (InnoDB):

Server version: 5.5.25a Source distribution

Dane wyjściowe (zwróć uwagę, jak szósta operacja blokuje się przez ~400ms potrzebnych do zakończenia aktualizacji indeksu):

 1  real    0m0.009s
 2  real    0m0.009s
 3  real    0m0.009s
 4  real    0m0.012s
 5  real    0m0.009s
Index Update - START
Index Update - FINISH
 6  real    0m0.388s
 7  real    0m0.009s
 8  real    0m0.009s
 9  real    0m0.009s
10  real    0m0.009s
11  real    0m0.009s

Vs odczytują operacje, które nie blokują (zamień komentarz linii w skrypcie):

 1  real    0m0.010s
 2  real    0m0.009s
 3  real    0m0.009s
 4  real    0m0.010s
 5  real    0m0.009s
Index Update - START
 6  real    0m0.010s
 7  real    0m0.010s
 8  real    0m0.011s
 9  real    0m0.010s
...
41  real    0m0.009s
42  real    0m0.010s
43  real    0m0.009s
Index Update - FINISH
44  real    0m0.012s
45  real    0m0.009s
46  real    0m0.009s
47  real    0m0.010s
48  real    0m0.009s

Aktualizacja schematu MySQL bez przestojów

Jak dotąd istnieje tylko jedna metoda, o której wiem, aby zaktualizować schemat MySql i nie dopuścić do awarii dostępności. Mistrzowie cyrkularni:

  • Master A ma uruchomioną bazę danych MySQL
  • Wprowadź Master B do użytku i poproś go o zreplikowanie zapisów z Master A (B jest niewolnikiem A)
  • Przeprowadź aktualizację schematu na Master B. Opóźni się podczas aktualizacji
  • Niech Mistrz B nadrobi zaległości. Niezmienny:Twoja zmiana schematu MUSI umożliwiać przetwarzanie poleceń replikowanych ze schematu starszej wersji. Zmiany w indeksowaniu kwalifikują się. Zwykle kwalifikują się proste dodawania kolumn. Usuwasz kolumnę? prawdopodobnie nie.
  • ATOMICZNIE zamień wszystkich klientów z Master A na Master B. Jeśli chcesz być bezpieczny (zaufaj mi, tak), upewnij się, że ostatni zapis do A jest replikowany do B PRZED B wykonuje swój pierwszy zapis. Jeśli zezwolisz na równoczesny zapis do 2+ masterów, ... lepiej zrozumiesz replikację MySQL na GŁĘBOKIM poziomie lub zmierzasz w świat bólu. Ekstremalny ból. Na przykład, czy masz kolumnę, która jest AUTOINCREMENT??? jesteś przerąbany (chyba że używasz parzystych liczb na jednym mistrzu i nieparzystych na drugim). NIE ufaj replikacji MySQL, że „robi to, co jest właściwe”. NIE jest sprytne i nie uratuje cię. Jest to po prostu nieco mniej bezpieczne niż kopiowanie binarnych dzienników transakcji z wiersza poleceń i ręczne ich odtwarzanie. Mimo to odłączenie wszystkich klientów od starego mastera i przerzucenie ich na nowy master można wykonać w ciągu kilku sekund, znacznie szybciej niż czekanie na wielogodzinną aktualizację schematu.
  • Teraz Mistrz B jest Twoim nowym mistrzem. Masz nowy schemat. Życie jest dobre. Mieć piwo; najgorsze minęło.
  • Powtórz proces z Mistrzem A, ulepszając jego schemat, aby stał się twoim nowym mistrzem drugorzędnym, gotowym do przejęcia w przypadku, gdy twój mistrz główny (teraz mistrz B) straci moc lub po prostu wstaje i umrze.

To nie jest łatwy sposób na aktualizację schematu. Możliwość pracy w poważnym środowisku produkcyjnym; Tak to jest. Proszę, proszę, jeśli istnieje prostszy sposób na dodanie indeksu do tabeli MySQL bez blokowania zapisów, daj mi znać.

Googling zaprowadził mnie do tego artykułu który opisuje podobną technikę. Co więcej, radzą pić w tym samym momencie procedury (pamiętaj, że napisałem swoją odpowiedź przed przeczytaniem artykułu)!

Zmiana schematu pt-online firmy Percona

artykuł Załączyłem powyżej rozmowy o narzędziu, pt -zmiana-schematu online , który działa w następujący sposób:

  • Utwórz nową tabelę o takiej samej strukturze jak oryginalna.
  • Zaktualizuj schemat w nowej tabeli.
  • Dodaj wyzwalacz do oryginalnej tabeli, aby zmiany były zsynchronizowane z kopią
  • Kopiuj partiami wiersze z oryginalnej tabeli.
  • Odsuń oryginalny stół i zastąp go nowym.
  • Upuść stary stół.

Sam nigdy nie próbowałem tego narzędzia. MMW

RDS

Obecnie używam MySQL za pośrednictwem RDS Amazon . To naprawdę fajna usługa, która podsumowuje i zarządza MySQL, pozwalając dodawać nowe repliki do odczytu za pomocą jednego przycisku i w przejrzysty sposób aktualizować bazę danych w ramach sprzętowych jednostek SKU. To naprawdę wygodne. Nie dostajesz SUPER dostępu do bazy danych, więc nie możesz bezpośrednio spieprzyć replikacji (czy to błogosławieństwo czy przekleństwo?). Możesz jednak użyć Promocja odczytu replik aby wprowadzić zmiany w schemacie na urządzeniu podrzędnym tylko do odczytu, a następnie promuj go, aby stał się nowym mistrzem. Dokładnie ta sama sztuczka, którą opisałem powyżej, tylko o wiele łatwiejsza do wykonania. Nadal nie robią zbyt wiele, aby pomóc ci w przejściu. Musisz ponownie skonfigurować i ponownie uruchomić aplikację.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Przywróć bazę danych mysql z plików .frm

  2. Naucz się podstawowych zapytań SQL przy użyciu MySQL

  3. MySQL SELECT WHERE datetime pasuje do dnia (a niekoniecznie do godziny)

  4. MySQL — Odzyskaj porzuconą bazę danych schematów wydajności

  5. Jak tworzyć i używać widoków MySQL