Zmodyfikuj DEFINER na wielu widokach

25

Mam problemy z utworzeniem kopii zapasowej moich baz danych po aktualizacji. Grzebię w moim systemie, próbując dowiedzieć się, dlaczego. Jedno zapytanie, które uruchomiłem, zwróciło ten wynik.

Got error: 1449: The user specified as a definer ('cittool'@'%') does not exist when using LOCK TABLES

Po pewnym dochodzeniu wydaje się, że definicją tych widoków jest stare konto programisty, które zostało usunięte z systemu. Bazy danych i widoki z tym problemem są używane bardzo rzadko, a większość z nich jest przechowywana do celów archiwalnych.

Istnieje około 40 widoków z definicjorem, który już nie istnieje. Czy istnieje prosty sposób na zmianę definicji konta na inne konto na raz? Czy istnieje sposób, aby mysqldump po prostu zrzucił wszystkie widoki do pliku, abym mógł edytować ten plik i odtworzyć te widoki?

Zoredache
źródło
dla mnie właśnie dodałem brakujące konto do bazy danych i błąd zniknął.
user1794918,

Odpowiedzi:

13

Utwórz plik tekstowy ze wszystkimi definicjami widoku:

mysql -uusername -ppassword -A --skip-column-names -e"SELECT CONCAT('SHOW CREATE VIEW ',table_schema,'.',table_name,'\\G') FROM information_schema.tables WHERE engine IS NULL" | mysql -uusername -ppassword -A --skip-column-names > AllMyViews.sql

Stamtąd edytujesz AllMyViews.sql. Następnie upuść widoki

mysql -uusername -ppassword -A --skip-column-names -e"SELECT CONCAT('DROP VIEW ',table_schema,'.',table_name,';') FROM information_schema.tables WHERE engine IS NULL" | mysql -uusername -ppassword -A

Po edycji AllMyViews.sql załaduj je ponownie

mysql -uusername -ppassword -A < AllMyViews.sql

Spróbuj !!!

RolandoMySQLDBA
źródło
+1 jako świetna alternatywa, jeśli definicja widoku informacji nie pojawia się, ale SHOW CREATE VIEW działa dobrze.
Derek Downey
Chociaż teoretycznie bardziej podobało mi się rozwiązanie DTest, coś w moim systemie uniemożliwiało jego działanie. Zasadniczo użyłem powyższego do zrzucenia instrukcji show create do pliku i musiałem ręcznie je trochę edytować, a następnie uruchomić.
Zoredache
POKAŻ UTWÓRZ WIDOK nie działa, gdy użytkownik definiujący nie istnieje - zgłasza ten sam błąd co mysqldump:The user specified as a definer ('abc'@'1.2.3.4') does not exist
Marki555
@ Marki555 Następnie musisz tymczasowo utworzyć tego użytkownika. biegnij CREATE USER 'abc'@'1.2.3.4';. Następnie spróbuj ponownie.
RolandoMySQLDBA
Właśnie zauważyłem, że widok korzysta z procedury składowanej i ten komunikat o błędzie jest odnoszony do definiatora tej procedury, a nie sam się wyświetla
Marki555 30.04.2014
25

Możesz użyć ALTER VIEW w połączeniu ze schematem informacyjnym . Wspomniałeś o zrzuceniu go do pliku tekstowego, więc może coś takiego:

SELECT CONCAT("ALTER DEFINER=`youruser`@`host` VIEW `",table_name,"` AS ", view_definition,";") 
FROM information_schema.views WHERE table_schema='databasename'

Wymieszaj to z wierszem poleceń mysql (zakładając, że * nix nie zna systemu Windows):

> echo "*abovequery*" | mysql -uuser -p > alterView.sql
> mysql -uuser -p databasename < alterView.sql

Sidenote: Nie można bezpośrednio zmieniać wpisów w schemacie informacji . Uwaga 2: Działa to tylko dla jednej bazy danych na raz, jeśli odrzucisz GDZIE schemat_tabeli, musisz wstawić między nimi polecenia USE.

Derek Downey
źródło
Podoba mi się to, ponieważ wygląda nieco mniej zaangażowane i bardziej zwięzłe niż moje. +1 !!! (Zapomniałem o ALTER VIEW)
RolandoMySQLDBA
Wiesz, dlaczego pole view_definition byłoby puste? SELECT table_name,view_definition FROM information_schema.views WHERE table_schema='cittmp'; powroty| Staff | |
Zoredache
Z dyskusji na czacie wygląda na to, że jest to problem z uprawnieniami z super przywilejem. bugs.mysql.com/bug.php?id=39733
Derek Downey
Idealne rozwiązanie! +1
Pablo Martinez
Przynajmniej w RedHat, jeśli wypisujesz do pliku, musisz uciec przed echo "SELECT CONCAT("ALTER DEFINER=\`youruser\`@\`host\` VIEW...
tykającymi znakami
3

Automatyzacja rozwiązania Dereka spowoduje zmianę DEFINERA na root@localhosti ustawienie SQL SECURITY INVOKER(upewnij się, że chcesz tego najpierw!) We wszystkich widokach we wszystkich bazach danych:

mysql -BNe 'show databases' | \
egrep -v '^(information_schema|performance_schema)$' | \
while read DB
do 
    mysql -BNe "SELECT CONCAT(\"ALTER DEFINER=\`root\`@\`localhost\` SQL SECURITY INVOKER VIEW \",table_name,\" AS \", view_definition,\";\") FROM information_schema.views WHERE table_schema=\"$DB\"" | \
    mysql $DB
done

OSTRZEŻENIE: upewnij się, że wykonałeś pełną kopię zapasową mysql (np. Zatrzymując mysqld i wykonując kopię zapasową wszystkich plików w katalogu / var / lib / mysql) przed jego uruchomieniem - na wszelki wypadek ... Dla mnie zadziałało, ale YMMV .

powinieneś również sprawdzić wszystkie swoje tabele / widoki za pomocą:

mysql -BNe 'show databases' | \
egrep -v '^(information_schema|performance_schema)$' | \
while read DB
do 
   mysql -BNe 'show tables' $DB | \
   while read t
   do
      echo "check table $t;"
   done | mysql -BN $DB
done | \
egrep -v 'status\s*OK'

nie powinien już narzekać na nieprawidłowe definicje w widokach.

Matija Nalis
źródło
Bezwstydnie dodał to do moich fragmentów. Dzięki!
stefgosselin
3

Wyeksportuj wszystkie widoki bazy danych <DB>:

mysql -BNe "SELECT TABLE_NAME FROM TABLES WHERE TABLE_SCHEMA = '<DB>' AND TABLE_TYPE = 'VIEW'" \
    information_schema | xargs mysqldump --single-transaction --no-data <DB> >views.sql

lub:

mysql -BNe "SELECT TABLE_NAME FROM VIEWS WHERE TABLE_SCHEMA = '<DB>'" \
    information_schema | xargs mysqldump --single-transaction --no-data <DB> >views.sql

Edytuj views.sql(zmień definicję) i utwórz je ponownie:

cat views.sql | mysql <DB>

Określ -ui -pprzełącz w razie potrzeby.

x-yuri
źródło
W jaki sposób należy views.sqledytować WIDOKI ? Jak je odtworzyć?
SherylHohman
@SherylHohman Zmień DEFINER = olduser@oldhostna DEFINER = newuser@newhost, cat views.sql | mysql <DB>odtwarza widoki.
x-yuri