MySQL Dumps से DEFINER क्लॉज निकालें


114

मेरे पास मेरे एक डेटाबेस का MySQL डंप है। इसमें, DEFINER क्लॉज़ हैं जो देखने में,

"DEFINER=`root`@`localhost`" 

अर्थात्, ये DEFINER क्लाज मेरे CREATE VIEW और CREATE PROCEDURE स्टेटमेंट पर हैं। क्या मेरी डंप फ़ाइल से इन DEFINER क्लॉस को हटाने का कोई तरीका है?


सालों पहले एक बग की सूचना दी गई थी, लेकिन यह छोड़ दिया गया लगता है: Bugs.mysql.com/bug.php?id=24680
1234ru

जवाबों:


109

मुझे नहीं लगता DEFINERकि डंप में एस जोड़ने में अनदेखी करने का एक तरीका है । लेकिन डंप फ़ाइल बनने के बाद उन्हें हटाने के तरीके हैं।

  1. पाठ संपादक में डंप फ़ाइल खोलें और DEFINER=root@localhostखाली स्ट्रिंग के साथ सभी घटनाओं को बदलें ""

  2. डंप (या पाइप उत्पादन) का उपयोग कर संपादित करें perl:

    perl -p -i.bak -e "s/DEFINER=\`\w.*\`@\`\d[0-3].*[0-3]\`//g" mydatabase.sql
  3. के माध्यम से उत्पादन पाइप sed:

    mysqldump ... | sed -e 's/DEFINER[ ]*=[ ]*[^*]*\*/\*/' > triggers_backup.sql

1
@ फैस्टट्रैक, कृपया पूरी स्ट्रिंग हटा दें।
अभय

3
मैं यह उल्लेख करने का सुझाव देता हूं कि DEFINER को हटाने के बजाय इसे CURRENT_USER पर सेट किया जा सकता है जैसे: sed -E 's/DEFINER=[^ ]+@ [^] + /DEFINER=CURRENT_USER/g' dump.sql > new_dump.sqlइसमें प्रतिबंध / पहुंच नियंत्रण रखने का लाभ है।
4thfloorstudios

27
sedआदेश प्रक्रियाओं और कार्यों से Definer खंड को दूर नहीं करता। यहां वर्धित संस्करण है जो विचारों, ट्रिगर, प्रक्रियाओं और कार्यों को संभालता है: sed -e 's/DEFINER[ ]*=[ ]*[^*]*\*/\*/' | sed -e 's/DEFINER[ ]*=[ ]*[^*]*PROCEDURE/PROCEDURE/' | sed -e 's/DEFINER[ ]*=[ ]*[^*]*FUNCTION/FUNCTION/'
व्लादिमीर स्ट्रैगत्स्की

4
FYI --- हालांकि इस उत्तर के समय ऐसा नहीं था, MySQL> 5.6 अब एक mysqldump (1) के साथ जहाज जो एक विकल्प के रूप में "--skip- निश्चित" का समर्थन करता है: dev.mysql.com/doc/refman / 5.7
en/

4
नहीं, यह mysqldump नहीं है, बल्कि mysql p ump है जिसके पास --skip-definer है।
Xdg

70

आप SED का उपयोग करके निकाल सकते हैं

sed -i 's/DEFINER=[^*]*\*/\*/g' mydump.sql

MacOS में:

sed -i '' 's/DEFINER=[^*]*\*/\*/g' mydump.sql

अलग-अलग होने के लिए मैकओएस में यहां क्या हो रहा है?
एलेक्स

1
मैक पर sed के लिए मैनपेज यह कहता है: -i extension"फाइलों को इन-प्लेस संपादित करें, बैकअप को निर्दिष्ट एक्सटेंशन के साथ सहेजा जा रहा है। यदि एक शून्य-लंबाई एक्सटेंशन दिया गया है, तो कोई बैकअप सहेजा नहीं जाएगा। जब यह शून्य-लंबाई एक्सटेंशन देने की अनुशंसा नहीं की जाती है। इन-प्लेस संपादन फ़ाइलें, जैसा कि आप उन स्थितियों में भ्रष्टाचार या आंशिक सामग्री को जोखिम में डालते हैं जहां डिस्क स्थान समाप्त हो गया है, आदि। "
चाड

यह जानकर अच्छा लगा, @ चड्ढा। मैं इस तरह से sed का उपयोग कर रहा हूँ MAC अब 5 + वर्ष के लिए। मुझे कभी भी स्पेस या दूषित फ़ाइलों की समस्या नहीं थी। लेकिन निश्चित रूप से, कुछ पर विचार करने के लिए है। स्पष्टीकरण देने के लिए धन्यवाद।
रिकार्डो मार्टिन्स

मैं उन मुद्दों पर मैक में कभी नहीं चला। बस मुझे लगा कि मैं स्पष्ट कर दूंगा क्योंकि @ एलेक्स ने पूछा :)
चाड

57

5.7.8 mysql संस्करण के बाद से आप --skip-definermysqlpump के साथ विकल्प का उपयोग कर सकते हैं , उदाहरण के लिए:

mysqlpump --skip-definer -h localhost -u user -p yourdatabase

Http://dev.mysql.com/doc/refman/5.7/en/mysqlpump.html#option_mysqlpump_skip-definer पर अपडेट किए गए mysql मैनुअल देखें


8
जो कोई भी आश्चर्यचकित होता है, उसके बीच क्या अंतर है - mysqldumpऔर mysqlpumpयहां से संबंधित प्रश्न है: dba.stackexchange.com/questions/118846/mysqldump-vs-mysqlpump
14

मेरे पास phpMyAdmin और MySQL Workbench इंस्टॉल है। मैं विंडोज पर इस कमांड को कैसे निष्पादित कर सकता हूं?
पॉसफ़न 12

(कुछ परीक्षणों के बाद: -1) यह उपयोग करता है information_schema.user, और यह हमेशा सभी उपयोगकर्ताओं के लिए पठनीय नहीं है
bato3

17

मैंने अपने खुद के mysqldump आउटपुट से DEFINER क्लॉज को हटाने के लिए इन विचारों का उपयोग किया, लेकिन मैंने एक सरल तरीका अपनाया:

बस !कोड और DEFINER से पहले हटा दें , और बाकी टिप्पणी नियमित टिप्पणी बन जाती है।

उदाहरण:

/*!50017 DEFINER=`user`@`111.22.33.44`*/

असहाय प्रदान किया जाता है, ऐसा करने से कम ।।

/* 50017 DEFINER=`user`@`111.22.33.44`*/

सबसे आसान regexp, हालांकि, को दूर करना है! और संख्या

mysqldump | /usr/bin/perl -pe 's/\!\d+ DEFINER/DEFINER/' > dumpfile.sql

यह हटाता है !#### DEFINERऔर DEFINER के साथ बदलता है ... आप DEFINER को भी हटा सकते हैं, यह वास्तव में मायने नहीं रखता है - एक बार "!" चला गया


16

दूसरे की सिफारिशों के अनुसार, यहाँ एक उदाहरण है कि डंप समाप्त होने के बाद, डफ़र को डंप से कैसे हटाया जाए:

mysqldump -u user --password='password' -h localhost database | grep -v "50013 DEFINER" > dump.sql

4
ट्रिगर्स के लिए, लाइन्स / *! 50003 क्रिएट * / * *! 50017 DEFINER = user@ localhost/ / / * की तरह दिखते हैं! 5000_ my_triggername से पहले के लिए इंसर्ट करें। और grep -vउन लाइनों को पूरी तरह से छोड़ देगा। (हालांकि 50017! = 50013)
केनी

13

जैसा कि दूसरों ने किसी भी तरह की नियमित अभिव्यक्ति के साथ निश्चित को अलग करने का उल्लेख किया है वह बहुत जटिल नहीं है। लेकिन दूसरे उदाहरणों ने मेरे लिए दृश्य परिभाषाएँ छीन लीं।

यह नियमित अभिव्यक्ति है जो मेरे लिए काम करती है:

sed -e 's/DEFINER=[^ ]* / /'

और तेज़ ^ ^ धन्यवाद
केविन लेबकोट

1
ट्रिगर के साथ काम नहीं करता है - यह भी हटा देता है */। MySQL 5.6.31।
फ्रैंच ड्रोबनिक्स

10

एक स्वचालित समाधान के लिए, आप देख सकते हैं mysqlmigrate। यह एक बैश रैपर है mysqldumpजिसके इर्द-गिर्द आपको डेटाबेस माइग्रेट करने और DEFINER स्टेटमेंट को अनदेखा करने की अनुमति मिलती है। उदाहरण:

$ mysqlmigrate -u root -p pass --ignore-definer from_db to_db

http://thesimplesynthesis.com/post/mysqlmigrate (या GitHub )

अन्यथा, हाँ, अभय अंक की तरह एक आदेश की जरूरत है:

$ mysqldump -u root -ppass the_db | sed -e 's/DEFINER[ ]*=[ ]*[^*]*\*/\*/' > the_db.sql

6

फाइल को हटाने के लिए OSX पर एक अन्य विकल्प:

sed -i '' 's/DEFINER=`[^`][^`]*`@`[^`][^`]*`//g' file.sql

5

आपको यहाँ उत्तर देखना चाहिए: /dba/9249/how-do-i-change-the-definer-of-a-view-in-mysql/29079##9079

इस समस्या को दूर करने के लिए मेरी राय में सबसे अच्छा तरीका, सेड या ग्रीप या किसी अन्य के साथ स्ट्रिंग के अतिरिक्त पार्स को जोड़ना नहीं है, इसके बजाय mysqldump --single-transaction को जोड़कर एक अच्छा डंप उत्पन्न करने में सक्षम है


क्यों उखाड़ा गया? इस उत्तर को उपयोगी क्यों नहीं माना जाता है?
जोस नोबेल

1
आपकी प्रतिक्रिया को अभी भी उस स्थिति को प्राप्त करने के लिए लगभग 90 upvotes की आवश्यकता है जो इसके हकदार हैं। आपके पास मेरा :)
पैट्रिक वैन बर्गन

4

ऐसा करने का एक त्वरित तरीका सशर्त टिप्पणियों में लिपटे बयानों को हटाने के लिए sed के माध्यम से mysqldump के आउटपुट को पाइप करना है । मैं बयानों से हटाने के लिए इसका उपयोग करता हूं , लेकिन आप अपने उद्देश्यों के अनुरूप रेगेक्स में शर्त टिप्पणी संस्करण संख्या को बदल सकते हैं।DEFINERDEFINERCREATE TRIGGER

mysqldump -u user --password='password' -h localhost database | \
  sed 's/\/\*!50017 DEFINER=`.*`@`.*`\*\///' 

1
थोड़ा अधिक पठनीय sed कथन: sed "s / DEFINER (? *?) FUNCTION / FUNCTION /"
reustmd

4

निश्चित नहीं है कि यह मदद करता है, लेकिन मैं SQLyog सामुदायिक संस्करण का उपयोग करता हूं, यहां उपलब्ध है: -

https://code.google.com/p/sqlyog/wiki/Downloads

डंपिंग एसक्यूएल या किसी अन्य डेटाबेस की नकल करते हुए यह आपको 'डेफिनर को इग्नोर' करने की अनुमति देता है

यह मुफ़्त है और बुनियादी कार्यक्षमता प्रदान करता है जो बहुत सारे लोगों की आवश्यकता होती है

वहाँ से एक भुगतान किया संस्करण भी उपलब्ध है: -

https://www.webyog.com/product/sqlyog

चियर्स


केवल ध्वज के रूप में 'उपयोगी नहीं' के बजाय शायद यह अधिक उपयोगी होगा यदि आप उत्तर देते हैं कि आपको क्यों लगता है कि यह उपयोगी नहीं है?
itfidds

3

मेरे लिए, यह काम करता है perl -p -i.bak -e "s/DEFINER=[^ |\s]*//g" yourdump.dmp:। इसने मेरे डंप से DEFINER = रूट @ लोकलहोस्ट को हटा दिया, प्रत्येक प्रक्रिया प्रक्रिया बनाने पर


2

MySQL 5.6.xऔर लिनक्स के लिए DEFINER सूचना को निकालने के लिए यहां एक पूर्ण कार्य समाधान है । (पर परीक्षण किया गयाCentOS 6.5 )।

सामान्य रूप से हमें निम्नलिखित प्रविष्टियों को मैसकल डंप (यदि डेटा और ट्रिगर्स / रूटीन / फ़ंक्शन के साथ लिया जाता है) से बदलना होगा।

/*!50013 DEFINER=`MYSQLUSER`@`localhost` SQL SECURITY DEFINER */
/*!50013 DEFINER=`MYSQLUSER`@`%` SQL SECURITY DEFINER */
CREATE DEFINER=`MYSQLUSER`@`%` PROCEDURE `PROCEDURENAME`(
CREATE DEFINER=`MYSQLUSER`@`localhost` PROCEDURE `PROCEDURENAME`(
CREATE DEFINER=`MYSQLUSER`@`%` FUNCTION `FUNCTIONNAME`(
CREATE DEFINER=`MYSQLUSER`@`localhost` FUNCTION `FUNCTIONNAME`(
/*!50003 CREATE*/ /*!50017 DEFINER=`MYSQLUSER`@`%`*/ /*!50003 TRIGGER `TRIGGERNAME`
/*!50003 CREATE*/ /*!50017 DEFINER=`MYSQLUSER`@`localhost`*/ /*!50003 TRIGGER `TRIGGERNAME`

डंप mysqldump कमांड के साथ लिया गया था।

mysqldump -uMYSQLUSER -pPASSWORD DATABASENAME -R > dbdump.sql

बिना किसी डीएफ़एनआर जानकारी के आवश्यक डंप फ़ाइल को तीन आदेशों के साथ प्राप्त किया जा सकता है।

Command-1    
sed -i 's|DEFINER=[^*]*\*|\*|g' [PATH/]dbdump.sql

Command-2
find -name [PATH/]dbdump.sql | xargs perl -pi -e "s/ DEFINER=\`MYSQLUSER\`@\`localhost\`//"

Command-3
find -name [PATH/]dbdump.sql | xargs perl -pi -e "s/ DEFINER=\`MYSQLUSER\`@\`%\`//"

यदि डंप फ़ाइल आपके वर्तमान फ़ोल्डर में है तो [PATH /] पर ध्यान न दें।

यदि तालिकाओं में डेटा बहुत बड़ा है, तो दो फ़ाइलों में डंप लें, एक डंप फ़ाइल में डेटा के साथ डंप लें और अन्य डंप फ़ाइल में केवल लिपियों के डंप लें (ट्रिगर / फ़ंक्शंस / प्रक्रियाएं।) और उपरोक्त तीन चलाएं। 2 डंप (स्क्रिप्ट) फ़ाइल पर कमांड।


1

अपने सभी निश्चित उपयोगकर्ताओं को CURRENT_USER से बदलें। बैकअप बनाने वाली मेरी स्क्रिप्ट में, मेरी प्रतिस्थापित स्क्रिप्ट इस तरह दिखती है:

ant.replaceregexp(file: "$buildDir/sql/setupDB.sql", match: "`${project.ext.prod_db_username}`@`%`", replace: "CURRENT_USER", byline: true);

जो वास्तव में सिर्फ ANT कह रहा है। फिर आपको इसके बारे में चिंता करने की ज़रूरत नहीं होगी।


1

लिनक्स मशीनों पर आप इस एक-लाइनर का उपयोग कर सकते हैं:

mysql -uuser -ppwd -A --skip-column-names -e"SELECT CONCAT('SHOW CREATE VIEW ',table_schema,'.',table_name,';') FROM information_schema.tables WHERE engine IS NULL and table_schema like 'mydb%'" | mysql -uuser -ppwd -A --skip-column-names | sed -rn 's/.*?VIEW ([^\s]+?) (AS .*?)\s([^\s]+?)\s([^\s]+?)/DROP VIEW \1;\nCREATE VIEW \1 \2;/p' | mysql -uuser -ppwd -A --skip-column-names

आपको केवल अपने DB उपयोगकर्ता क्रेडेंशियल्स और डेटाबेस नाम / जैसे पैटर्न के साथ बोल्ड को बदलना होगा।

यहाँ अधिक जानकारी: http://blog.novoj.net/2014/05/16/recreate-mysql-views-without-definer-one-liner-solution-linux/


1

एकमात्र तरीका जो मैं इसे विंडोज के तहत काम कर सकता था:

कमांड लाइन में sed करने के लिए http://gnuwin32.sourceforge.net/ स्थापित करें और इसे Windows PATH: D: \ प्रोग्राम \ GetGnuWin32 \ bin में जोड़ें;

sed -i "s|DEFINER=`mydbuser`@`%%` SQL SECURITY DEFINER||g" "D:/prod_structure.sql"

sed -i "s|DEFINER=`mydbuser`@`%%`||g" "D:/prod_structure.sql"

mysqldump -P{port} -h{host} -u{user} -p{password} --routines --no-data --lock-tables=false database_prod > D:\prod_structure.sql

1

संकेत के लिए आप सभी का धन्यवाद। आलसी होने के कारण, मैंने एक स्क्रिप्ट लिखी जिसका नाम है: "MYsqldump":

DB=$1
HOST=$2
USER=$3
MYSQLDUMP='/usr/bin/mysqldump'
PARAMS="--complete-insert --disable-keys=0 --extended-insert=0 --routines=0 --skip-comments"
DAY=`date +%d`
MONTH=`date +%m`
YEAR=`date +%Y`
FILE=$DB.$DAY-$MONTH-$YEAR.sql

    if (( $# < 3 )) ; then
        echo ""
        echo "usage: MYsqldump <db> <host> <user>"
        echo ""
        exit 1
    fi

    $MYSQLDUMP -h $HOST -u $USER -p  $PARAMS $DB | grep -v '/*!50013 DEFINER' > $FILE

1

कुछ इस तरह के लिए:

DELIMITER ;;
निर्माता DEFINER = `mydb` @` localhost` समारोह `myfunction` () रिट्स इंट (11)
शुरू
(...)
समाप्त ;;

इसे इस्तेमाल करे:

mysqldump --force --routines --opt --user = myuser --dat डेटाबेस mydb | sed -e 's / DEFINER = `। *` @ `। *` \ // g'

1
  1. किसी भी संपादक के साथ अपना डेटाबेस खोलें, मैंने नोटपैड ++ के साथ प्रयोग किया,

  2. सभी परीक्षण खोजें DEFINER=root@localhost और इसे कुछ भी नहीं ( "") IE के साथ बदलें । इसे मिटाओ।

फिर आप इसे अपने इच्छित होस्ट पर आयात कर सकते हैं।


0

सभी वस्तुओं के साथ मेरे लिए सबसे सरल रीगेक्स है:

sed 's/DEFINER=[^ ]*`//' ...

ध्यान दें जो quote-namesहोना है TRUE(जो डिफ़ॉल्ट रूप से है)।

उम्मीद है कि नए संस्करणों --skip-definerमें mysqlpump को 5.7 संस्करण में पेश किया गया स्विच mysqldump पर भी आता है।


0

मैंने सभी पंक्तियों को हटाने के लिए PowerShell स्क्रिप्ट का उपयोग किया है DEFINER:

get-content $ file_in_full_path | select-string -pattern $ line_string_delete -notmatch | आउट-फ़ाइल-एक्सपोज़र 1000000000-डिफ़ॉल्ट डिफ़ॉल्ट $ file_out_full_path


0

मेरे लिए कुछ भी काम नहीं कर रहा था, इसलिए मुझे अपना रेगेक्स लिखने की जरूरत थी।

  1. अपने डेटाबेस को फ़ाइल, catपूरी फ़ाइल में डंप करने की कोशिश करें और grepउन्हें देखने के लिए केवल आपके निश्चित कथन।

    cat file.sql | grep -o -E '। {, 60} DEFINER। {, 60}'

  2. अपना रेगेक्स लिखें

  3. इस रेगेक्स के साथ अपने डंप को सीड में पाइप करें। उदाहरण के लिए मेरा बयान है:

    mysqldump | sed -E 's // *! 500 [0-9] [0-9] DEFINER =। +? * ///' | sed -E 's / DEFINER = ?[^ ]+?? @ ?[^ ]+?? //'

  4. फायदा!


0

remove_definers.bat:

@echo off
(for /f "tokens=1,2*" %%a in (dumpfile.sql) do (
 if "%%b"=="" (echo %%a) else (
  echo %%b | find "DEFINER" > null && echo %%a %%c || echo %%a %%b %%c
 )
)) > dumpfile_nodefiners.sql
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.