Modifica DEFINER in molte viste


25

Ho problemi con il backup dei miei database dopo un aggiornamento. Ho cercato il mio sistema cercando di capire perché. Una query che ho eseguito ha restituito questo risultato.

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

Dopo alcune indagini sembra che il definitore di queste viste sia un vecchio account sviluppatore che è stato eliminato dal sistema. I database e le viste con questo problema vengono utilizzati molto raramente e la maggior parte viene conservata per scopi di archiviazione.

Esistono circa 40 visualizzazioni con un definitore che non esiste più. C'è un modo semplice per cambiare il definitore in un altro account su tutto in una volta? C'è un modo per convincere mysqldump a scaricare semplicemente tutte le viste in un file in modo da poterlo modificare e ricreare le viste?


per me, ho appena aggiunto l'account mancante al database e l'errore è andato via.
user1794918

Risposte:


13

Crea un file di testo con tutte le definizioni della vista:

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

Modifichi AllMyViews.sql da lì. Quindi, rilascia le viste

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

Dopo aver modificato AllMyViews.sql ricaricarli

mysql -uusername -ppassword -A < AllMyViews.sql

Provaci !!!


+1 come ottima alternativa se view_definition di information_schema non viene visualizzato ma SHOW CREATE VIEW funziona correttamente.
Derek Downey, il

Mentre in teoria mi piaceva la soluzione di DTest, qualcosa sul mio sistema stava impedendo che funzionasse. Ho praticamente usato quanto sopra per scaricare le istruzioni create show in un file e ho dovuto modificarle un po 'manualmente e quindi eseguirle.
Zoredache,

SHOW CREATE VIEW non funziona quando l'utente definitore non esiste - genera lo stesso errore di mysqldump:The user specified as a definer ('abc'@'1.2.3.4') does not exist
Marki555

@ Marki555 Quindi, è necessario creare quell'utente temporaneamente. corri CREATE USER 'abc'@'1.2.3.4';. Quindi riprova.
RolandoMySQLDBA

Ho appena notato che la vista utilizza alcune stored procedure e che il messaggio di errore è stato realizzato per il definitore di quella procedura, non per visualizzare se stesso
Marki555

25

È possibile utilizzare ALTER VIEW insieme allo schema delle informazioni . Hai detto di scaricarlo in un file di testo, quindi forse qualcosa del genere:

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

Mescola questo con la riga di comando mysql (supponendo * nix, che non ha familiarità con Windows):

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

Sidenote: non è possibile modificare direttamente le voci information_schema . Nota2: funziona solo per un database alla volta, se si interrompe DOVE table_schema è necessario inserire i comandi USE tra ciascuno.


Mi piace perché sembra un po 'meno coinvolto e più conciso del mio. +1 !!! (Ho dimenticato ALTER VIEW)
RolandoMySQLDBA il

Qualche idea sul perché il campo view_definition sarebbe vuoto? SELECT table_name,view_definition FROM information_schema.views WHERE table_schema='cittmp'; ritorna| Staff | |
Zoredache il

Dalla discussione in chat, sembra che sia un problema di autorizzazione con il super privilegio. bugs.mysql.com/bug.php?id=39733
Derek Downey,

Soluzione perfetta! +1
Pablo Martinez,

Almeno su RedHat, se stai inviando un file devi sfuggire ai echo "SELECT CONCAT("ALTER DEFINER=\`youruser\`@\`host\` VIEW...
segni di spunta

3

Automatizzando la soluzione di Derek, questo cambierà DEFINER root@localhoste imposterà SQL SECURITY INVOKER(assicurati di volerlo prima!) In tutte le viste in tutti i database:

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

ATTENZIONE: assicurati di aver effettuato un backup completo di mysql (es. Arrestando mysqld e eseguendo il backup di tutti i file in / var / lib / mysql) prima di eseguirlo - nel caso in cui ... Ha funzionato per me, ma YMMV .

dovresti anche controllare tutti i tuoi tavoli / viste con:

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'

non dovrebbe più lamentarsi delle definizioni non valide nelle viste.


Shamelessly ha aggiunto questo ai miei frammenti. Grazie!
stefgosselin,

3

Esporta tutte le visualizzazioni del database <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

o:

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

Modifica views.sql(cambia definizione) e ricrearli:

cat views.sql | mysql <DB>

Specificare -ue -pcambiare se necessario.


In che modo le VISUALIZZAZIONI dovrebbero views.sqlessere modificate? Inoltre, come ricrearli?
SherylHohman,

@SherylHohman Passa DEFINER = olduser@oldhosta DEFINER = newuser@newhost, cat views.sql | mysql <DB>ricrea i punti di vista.
x-yuri,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.