Ubah DEFINER pada Banyak Tampilan

25

Saya mengalami masalah dalam mencadangkan basis data setelah pembaruan. Saya telah mencari-cari di sistem saya mencoba mencari tahu mengapa. Satu permintaan yang saya jalankan mengembalikan hasil ini.

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

Setelah beberapa penyelidikan, tampaknya definisi untuk pandangan ini adalah akun pengembang lama yang telah dihapus dari sistem. Basis data dan pandangan dengan masalah ini jarang digunakan, dan sebagian besar disimpan untuk keperluan arsip.

Ada sekitar 40 tampilan dengan definisi yang tidak ada lagi. Apakah ada cara mudah untuk mengubah definisi ke akun berbeda pada semuanya sekaligus? Apakah ada cara untuk mendapatkan mysqldump dengan hanya membuang semua tampilan ke file sehingga saya bisa mengedit file itu dan membuat ulang tampilan?

Sakit kepala
sumber
bagi saya, saya baru saja menambahkan akun yang hilang ke database dan kesalahan hilang.
user1794918

Jawaban:

13

Buat file teks dengan semua definisi tampilan:

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

Anda mengedit AllMyViews.sql dari sana. Lalu, Jatuhkan Tampilan

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

Setelah mengedit AllMyViews.sql, muat ulang

mysql -uusername -ppassword -A < AllMyViews.sql

Cobalah !!!

RolandoMySQLDBA
sumber
Memberi +1 sebagai alternatif yang bagus jika view_definition information_schema tidak muncul tetapi SHOW CREATE VIEW berfungsi dengan baik.
Derek Downey
Sementara saya lebih suka solusi DTest dalam teori, sesuatu tentang sistem saya mencegahnya bekerja. Saya pada dasarnya menggunakan yang di atas untuk membuang acara membuat pernyataan ke file, dan saya harus mengeditnya secara manual dan kemudian menjalankannya.
Zoredache
TAMPILKAN CREATE VIEW tidak berfungsi ketika pengguna definisi tidak ada - itu melempar kesalahan yang sama seperti mysqldump:The user specified as a definer ('abc'@'1.2.3.4') does not exist
Marki555
@ Marki555 Kemudian, Anda harus membuat pengguna itu untuk sementara. lari CREATE USER 'abc'@'1.2.3.4';. Lalu, coba lagi.
RolandoMySQLDBA
Saya hanya memperhatikan bahwa View menggunakan beberapa prosedur tersimpan dan pesan kesalahan tersebut direalisasikan ke definisi prosedur itu, bukan melihatnya sendiri
Marki555
25

Anda dapat menggunakan ALTER VIEW bersamaan dengan skema informasi . Anda menyebutkan membuangnya ke file teks, jadi mungkin sesuatu seperti ini:

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

Campur ini dengan baris perintah mysql (dengan asumsi * nix, tidak akrab dengan windows):

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

Sidenote: Anda tidak dapat mengubah entri information_schema secara langsung . Note2: Ini hanya berfungsi untuk satu database pada satu waktu, jika Anda pergi dari WHERE table_schema Anda harus memasukkan perintah USE antara masing-masing.

Derek Downey
sumber
Saya suka ini karena terlihat sedikit kurang terlibat dan lebih ringkas daripada milik saya. +1 !!! (Saya lupa tentang ALTER VIEW)
RolandoMySQLDBA
Adakah gagasan mengapa bidang view_definition akan kosong? SELECT table_name,view_definition FROM information_schema.views WHERE table_schema='cittmp'; kembali| Staff | |
Zoredache
Dari diskusi di obrolan, sepertinya itu masalah izin dengan hak istimewa super. bugs.mysql.com/bug.php?id=39733
Derek Downey
Solusi sempurna! +1
Pablo Martinez
Setidaknya pada RedHat, jika Anda menghasilkan file Anda harus menghindari kutu kembali, misalnyaecho "SELECT CONCAT("ALTER DEFINER=\`youruser\`@\`host\` VIEW...
clav
3

Mengotomatiskan pada solusi Derek, ini akan mengubah DEFINER ke root@localhostdan mengatur SQL SECURITY INVOKER(pastikan Anda menginginkannya terlebih dahulu!) Di semua tampilan di semua 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

PERINGATAN: pastikan Anda telah membuat cadangan mysql penuh (mis. Dengan menghentikan mysqld, dan mencadangkan semua file di / var / lib / mysql) sebelum Anda menjalankannya - untuk berjaga-jaga ... Itu bekerja untuk saya, tetapi YMMV .

Anda juga harus memeriksa semua tabel / tampilan Anda dengan:

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'

seharusnya tidak lagi mengeluh tentang definisi yang tidak valid dalam tampilan.

Matija Nalis
sumber
Tanpa malu-malu menambahkan ini ke cuplikan saya. Terima kasih!
stefgosselin
3

Ekspor semua tampilan basis data <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

atau:

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

Edit views.sql(ubah definisi) dan buat kembali:

cat views.sql | mysql <DB>

Tentukan -udan -paktifkan jika perlu.

x-yuri
sumber
Dengan cara apa VIEWS views.sql, harus diedit? Juga, bagaimana cara membuatnya kembali?
SherylHohman
@SherylHohman Ubah DEFINER = olduser@oldhostke DEFINER = newuser@newhost, buat cat views.sql | mysql <DB>ulang tampilan.
x-yuri