แก้ไข DEFINER ในหลาย ๆ มุมมอง


25

ฉันมีปัญหาในการสำรองฐานข้อมูลของฉันหลังจากการอัพเดต ฉันแหย่ระบบของฉันพยายามหาสาเหตุ ฉันค้นหาหนึ่งรายการส่งคืนผลลัพธ์นี้

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

หลังจากการตรวจสอบบางอย่างปรากฏว่าตัวระบุสำหรับมุมมองเหล่านี้เป็นบัญชีนักพัฒนาซอฟต์แวร์เก่าที่ถูกลบออกจากระบบ ฐานข้อมูลและมุมมองที่มีปัญหานี้มีการใช้งานไม่บ่อยนักและส่วนใหญ่ถูกเก็บไว้เพื่อการเก็บถาวร

มีประมาณ 40 มุมมองที่มีตัวกำหนดที่ไม่มีอยู่อีกต่อไป มีวิธีง่ายๆในการเปลี่ยนผู้กำหนดเป็นบัญชีที่แตกต่างกันในทุกสิ่งในครั้งเดียวหรือไม่? มีวิธีรับ mysqldump เพียงแค่ถ่ายโอนมุมมองทั้งหมดออกไปยังไฟล์ดังนั้นฉันสามารถแก้ไขไฟล์นั้นและสร้างมุมมองใหม่ได้หรือไม่


สำหรับฉันฉันเพิ่งเพิ่มบัญชีหายไปในฐานข้อมูลและข้อผิดพลาดก็หายไป
user1794918

คำตอบ:


13

สร้างไฟล์ข้อความที่มีคำจำกัดความมุมมองทั้งหมด:

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

คุณแก้ไข AllMyViews.sql จากที่นั่น จากนั้นปล่อยมุมมอง

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

หลังจากแก้ไข AllMyViews.sql แล้วโหลดซ้ำอีกครั้ง

mysql -uusername -ppassword -A < AllMyViews.sql

ให้มันลอง !!!


+1 เป็นทางเลือกที่ดีถ้า view_definition ของ data_schema ไม่ปรากฏขึ้น แต่ SHOW CREATE VIEW ทำงานได้ดี
Derek Downey

ในขณะที่ฉันชอบวิธีแก้ปัญหาของ DTest ที่ดีขึ้นในทางทฤษฎีบางอย่างเกี่ยวกับระบบของฉันก็ป้องกันไม่ให้มันทำงาน ฉันโดยทั่วไปใช้ด้านบนเพื่อถ่ายโอนรายการสร้างคำสั่งเป็นไฟล์และฉันต้องแก้ไขด้วยตนเองเล็กน้อยจากนั้นเรียกใช้พวกเขา
Zoredache

SHOW CREATE VIEW ไม่ทำงานเมื่อไม่มีผู้ใช้ definer - มีข้อผิดพลาดเหมือนกับ mysqldump:The user specified as a definer ('abc'@'1.2.3.4') does not exist
Marki555

@ Marki555 จากนั้นคุณต้องสร้างผู้ใช้นั้นชั่วคราว CREATE USER 'abc'@'1.2.3.4';วิ่ง จากนั้นลองอีกครั้ง
RolandoMySQLDBA

ฉันเพิ่งสังเกตว่า View ใช้โพรซีเดอร์ที่เก็บไว้บางส่วนและข้อความแสดงข้อผิดพลาดนั้นได้รับการกำหนดให้กับโพรซีเดอร์ของโพรซีเดอร์นั้นไม่ใช่ตัวของมันเอง
Marki555

25

คุณสามารถใช้ALTER VIEWร่วมกับสคีข้อมูล คุณพูดถึงการทิ้งมันลงในไฟล์ข้อความดังนั้นบางทีสิ่งนี้:

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

ผสมกับบรรทัดคำสั่ง mysql (สมมติว่า * ระวังไม่คุ้นเคยกับ windows):

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

Sidenote: คุณไม่สามารถปรับเปลี่ยนรายการ information_schema โดยตรง Note2: ใช้งานได้กับฐานข้อมูลเดียวเท่านั้นในแต่ละครั้งหากคุณออกจากที่ใด table_schema คุณต้องแทรกคำสั่ง USE ระหว่างแต่ละรายการ


ฉันชอบสิ่งนี้เพราะมันดูเกี่ยวข้องน้อยกว่าและกระชับกว่าของฉันเล็กน้อย +1 !!! (ฉันลืมเกี่ยวกับ ALTER VIEW)
RolandoMySQLDBA

มีความคิดใดบ้างที่ว่าทำไมฟิลด์ view_definition จะว่างเปล่า SELECT table_name,view_definition FROM information_schema.views WHERE table_schema='cittmp'; ผลตอบแทน| Staff | |
Zoredache

จากการสนทนาในการแชทดูเหมือนว่ามันเป็นปัญหาสิทธิ์ด้วยสิทธิ์พิเศษ bugs.mysql.com/bug.php?id=39733
Derek Downey

โซลูชั่นที่สมบูรณ์แบบ! +1
Pablo Martinez

อย่างน้อยใน RedHat หากคุณกำลังส่งออกไปยังไฟล์ที่คุณต้องหลบหนีเห็บหลังเช่นecho "SELECT CONCAT("ALTER DEFINER=\`youruser\`@\`host\` VIEW...
clav

3

โดยอัตโนมัติในโซลูชันของ Derek สิ่งนี้จะเปลี่ยน DEFINER เป็นroot@localhostและตั้งค่าSQL SECURITY INVOKER(ให้แน่ใจว่าคุณต้องการก่อน!) ในมุมมองทั้งหมดในฐานข้อมูลทั้งหมด:

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

คำเตือน: ตรวจสอบให้แน่ใจว่าคุณได้ทำการสำรองข้อมูลแบบเต็ม mysql (เช่นหยุด mysqld และสำรองไฟล์ทั้งหมดใน / var / lib / mysql) ก่อนที่จะรัน - ในกรณี ... มันใช้งานได้สำหรับฉัน แต่ YMMV .

คุณควรตรวจสอบตาราง / มุมมองทั้งหมดของคุณด้วย:

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'

ไม่ควรบ่นเกี่ยวกับการกำหนดที่ไม่ถูกต้องในมุมมอง


เพิ่มอย่างนี้ลงในส่วนย่อยของฉันอย่างไม่มีจุดหมาย ขอบคุณ!
stefgosselin

3

ส่งออกมุมมองทั้งหมดของฐานข้อมูล<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

หรือ:

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

แก้ไขviews.sql(เปลี่ยนผู้กำหนด) และสร้างใหม่:

cat views.sql | mysql <DB>

ระบุ-uและ-pสวิตช์หากจำเป็น


VIEWS views.sqlควรแก้ไขอย่างไร? นอกจากนี้วิธีการสร้างใหม่ได้อย่างไร
SherylHohman

@SherylHohman เปลี่ยนDEFINER = olduser@oldhostไปDEFINER = newuser@newhost, cat views.sql | mysql <DB>สร้างมุมมอง
x-yuri
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.