DEFINER yan tümcesini MySQL Dumps'tan kaldır


114

Veritabanlarımdan birinin MySQL dökümü var. İçinde DEFINER cümleleri var gibi görünüyor,

"DEFINER=`root`@`localhost`" 

Yani bu DEFINER cümleleri CREATE VIEW ve CREATE PROCEDURE ifadelerimde. Bu DEFINER cümleciklerini döküm dosyamdan kaldırmanın bir yolu var mı?


Yıllar önce bir hata bildirildi, ancak terk edilmiş görünüyor: bugs.mysql.com/bug.php?id=24680
1234ru

Yanıtlar:


109

Çöplüğe DEFINERs eklemeyi göz ardı etmenin bir yolu olduğunu sanmıyorum . Ancak döküm dosyası oluşturulduktan sonra bunları kaldırmanın yolları vardır.

  1. Döküm dosyasını bir metin düzenleyicide açın ve tüm oluşumlarını DEFINER=root@localhostboş bir "" dizesiyle değiştirin

  2. Aşağıdakileri kullanarak dökümü düzenleyin (veya çıktıyı yönlendirin) perl:

    perl -p -i.bak -e "s/DEFINER=\`\w.*\`@\`\d[0-3].*[0-3]\`//g" mydatabase.sql
  3. Çıkışı şu şekilde yönlendirin sed:

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

1
@FastTrack, lütfen dizenin tamamını kaldırın.
Abhay

3
DEFINER'ı kaldırmak yerine şu şekilde CURRENT_USER olarak ayarlanabileceğini belirtmek isterim: sed -E 's/DEFINER=[^ ]+@ [^] + /DEFINER=CURRENT_USER/g' dump.sql > new_dump.sqlKısıtlamaları / erişim kontrolünü tutma avantajına sahiptir.
4thfloorstudios

27
sedKomut usul ve işlevlerden DEFINER maddesini kaldırmaz. İşte görünümleri, tetikleyicileri, prosedürleri ve işlevleri işleyen gelişmiş sürüm: sed -e 's/DEFINER[ ]*=[ ]*[^*]*\*/\*/' | sed -e 's/DEFINER[ ]*=[ ]*[^*]*PROCEDURE/PROCEDURE/' | sed -e 's/DEFINER[ ]*=[ ]*[^*]*FUNCTION/FUNCTION/'
Vladimir Strugatsky

4
Bilginize - bu cevabın verildiği sırada durum böyle olmasa da, MySQL> 5.6 artık seçenek olarak "--skip-definer" ı destekleyen bir mysqldump (1) ile birlikte geliyor: dev.mysql.com/doc/refman /5.7/en/...
Kevin_Kinsey

4
Hayır, mysqldump değil , --skip-tanımlayıcı olan mysql p ump.
Xdg

70

SED kullanarak kaldırabilirsiniz

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

MacOS'ta:

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

MacOS'ta farklı olmak için burada neler oluyor?
Alex

1
Mac için sed için manpage şunu söyler: -i extension"Dosyaları yerinde düzenleyin, belirtilen uzantı ile yedekleri kaydedin. Sıfır uzunluklu bir uzantı verilirse, yedekleme kaydedilmeyecektir. Disk alanının tükendiği vb. durumlarda bozulma veya kısmi içerik riski taşıdığınız için dosyaları yerinde düzenleme. "
Çad

Bunu bilmek güzel @Chad. Mac'te 5+ yıldır böyle sed kullanıyorum. Hiç boşluk veya bozuk dosyalarda sorun yaşamadım. Ama elbette dikkate alınması gereken bir şey. Açıkladığınız için teşekkürler.
Ricardo Martins

Mac'te de bu sorunlarla hiç karşılaşmadım. @Alex sorduğundan beri açıklığa kavuşturacağımı düşündüm :)
Chad

57

Mysql --skip-definer5.7.8 sürümünden beri, seçeneği mysqlpump ile kullanabilirsiniz, örneğin:

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

Http://dev.mysql.com/doc/refman/5.7/en/mysqlpump.html#option_mysqlpump_skip-definer adresindeki güncellenmiş mysql kılavuzuna bakın


8
Arasındaki fark ne merak kim için mysqldumpve mysqlpump- burada ilgili soru şudur: dba.stackexchange.com/questions/118846/mysqldump-vs-mysqlpump
Scadge

PhpMyAdmin ve MySQL Workbench'i kurdum. Bu komutu Windows'ta nasıl çalıştırırım?
posfan12

(bazı testlerden sonra: -1) kullanır information_schema.userve bu tüm kullanıcılar için her zaman okunabilir değildir
bato3

17

DEFINER cümlesini kendi mysqldump çıktımdan çıkarmak için bu fikirleri kullandım, ancak daha basit bir yaklaşım izledim:

!Kodun önündeki ve TANIMLAYICI'yı kaldırmanız yeterlidir ve yorumun geri kalanı normal bir yorum haline gelir.

Misal:

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

çaresiz kılınmış, bunu yapmak kadar az ...

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

En kolay regexp, yine de! ve sayılar

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

Bu !#### DEFINER, DEFINER ile kaldırılır ve yerine geçer ... DEFINER'ı da kaldırabilirsiniz, gerçekten önemli değil - bir kez "!" gitti


16

Diğerlerinin tavsiyelerine göre, döküm bittikten sonra DEFINER'ın çöplükten nasıl kaldırılacağına dair bir örnek:

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

4
Tetikleyiciler için, satırlar şöyle görünür: / *! 50003 CREATE * / / *! 50017 DEFINER = user@ localhost* / / *! 50003, my_triggername, HER SATIR İÇİN my_table ÜZERİNE EKLE ... * / ;; ve grep -vbu satırları tamamen bırakacak. (50017! = 50013 olmasına rağmen)
Kenney

13

Diğerlerinin de bahsettiği gibi, tanımlayıcıyı herhangi bir düzenli ifade ile çıkarmak çok karmaşık değildir. Ancak diğer örnekler benim için görüş tanımlarını ortadan kaldırdı.

Bu benim için çalışan normal ifadedir:

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

Ve daha hızlı ^^ Teşekkürler
Kevin Labécot

1
Tetikleyicilerle çalışmaz - ayrıca */. MySQL 5.6.31.
Franc Drobnič

10

Otomatik bir çözüm için bakabilirsiniz mysqlmigrate. mysqldumpVeritabanlarını taşımanıza ve DEFINER ifadelerini görmezden gelmenize izin veren bir Bash sarmalayıcısıdır . Misal:

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

http://thesimplesynthesis.com/post/mysqlmigrate (veya GitHub )

Aksi takdirde, evet, Abhay'in işaret ettiği gibi bir komuta ihtiyaç vardır:

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

6

OSX'te dosyadaki tanımlayıcıları kaldırmak için başka bir seçenek:

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

5

Cevaba şu adresten bakmalısınız: /dba/9249/how-do-i-change-the-definer-of-a-view-in-mysql/29079#29079

Bence bu sorunu çözmenin en iyi yolu, sed veya grep veya başka bir şeyle fazladan bir dize ayrıştırması eklememek, bunun yerine mysqldump --single-transaction ekleyerek iyi bir döküm oluşturabilir.


Neden olumsuz oy verildi? Bu cevap neden yararlı kabul edilmiyor?
Jose Nobile

1
Cevabınızın hak ettiği konumu elde etmek için hala yaklaşık 90 ek oy gerekiyor. Benimki sende :)
Patrick van Bergen

4

Bunu yapmanın hızlı bir yolu , koşullu açıklamalara sarılmış ifadeleri kaldırmak için mysqldump çıktısını sed aracılığıyla kanalize etmektir DEFINER. Ben kaldırmak için kullanabilir DEFINERgelen CREATE TRIGGERifadeleri, ancak amaçlara uygun regex koşul comment sürüm numarasını ince ayar yapabilirsiniz.

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

1
Biraz daha okunabilir bir sed ifadesi: sed "s / DEFINER (. *?) FUNCTION / FUNCTION /"
reustmd

4

Yardımcı olup olmadığından emin değilim ama şu adreste bulunan SQLyog Community Edition'ı kullanıyorum: -

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

Sql dökümünü atarken veya başka bir veritabanına kopyalarken, 'DEFINER'ı Yoksaymanıza' izin verir.

Ücretsizdir ve birçok insanın ihtiyaç duyduğu temel işlevleri sağlar

Aşağıdakilerden ücretli bir sürüm de mevcuttur: -

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

Şerefe


"Yararlı değil" olarak işaretlemek yerine, belki de neden yararlı olmadığını düşündüğünüzü yanıtlarsanız daha yararlı olabilir mi?
itfidds

3

Benim için bu çalışır: perl -p -i.bak -e "s/DEFINER=[^ |\s]*//g" yourdump.dmp. Bu DEFINER = root @ localhost'u her oluşturma prosedürü ifadesindeki dökümümden kaldırdı


2

İşte MySQL 5.6.xLinux için DEFINER bilgilerini kaldırmak için eksiksiz bir çalışma çözümü . (Test edildi CentOS 6.5).

Genellikle Mysql dökümünden aşağıdaki girişleri değiştirmemiz gerekir (veriler ve tetikleyiciler / rutinler / işlevlerle birlikte alınırsa).

/*!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`

Döküm, aşağıdaki mysqldump komutu ile alınmıştır.

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

DEFINER bilgisi içermeyen gerekli döküm dosyası aşağıdaki üç komutla elde edilebilir.

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\`@\`%\`//"

Döküm dosyası mevcut klasörünüzdeyse, [PATH /] 'i yoksayın.

Tablolardaki veriler çok büyükse, dökümü iki dosyaya alın, bir döküm dosyasında veri dökümü alın ve diğer döküm dosyasında yalnızca komut dosyalarının dökümünü alın (Tetikleyiciler / Fonksiyonlar / Prosedürler.) Ve yukarıdaki üç dosyayı çalıştırın. 2. döküm (betikler) dosyasındaki komutlar.


1

Tüm tanımlayıcı kullanıcılarınızı CURRENT_USER ile değiştirin. Yedeği oluşturan gradle komut dosyamda, değiştirme komut dosyam şöyle görünüyor:

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

bu gerçekten ANT'yi çağırıyor. O zaman bunun için endişelenmene gerek kalmayacak.


1

Linux makinelerde şu tek satırlı programı kullanabilirsiniz:

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

Yalnızca kalın yazılan dizeleri DB kullanıcı kimlik bilgileriniz ve veritabanı adınız / benzeri modelinizle değiştirmeniz gerekir.

Daha fazla bilgi burada: http://blog.novoj.net/2014/05/16/recreate-mysql-views-without-definer-one-liner-solution-linux/


1

Windows altında çalıştırabilmemin tek yolu:

Yükleme http://gnuwin32.sourceforge.net/ etmiş sed komut satırında ve Windows eklemek PATH: D: \ programları \ 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

İpuçları için hepinize teşekkür ederim. Tembel olarak "MYsqldump" adlı bir komut dosyası yazdım:

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

Şunun gibi bir şey için:

DELIMITER ;;
CREATE DEFINER = `mydb` @` localhost` FUNCTION` myfunction` () RETURNS int (11)
başla
(...)
son ;;

Bunu dene:

mysqldump --force - rutinler --opt --user = myuser --databases mydb | sed -e 's / DEFINER = ". *" @ ". *` \ // g'

1
  1. veritabanınızı herhangi bir editör ile açın, notepad ++ ile kullandım,

  2. tüm testleri bulun DEFINER=root@localhost ve hiçbir şeyle değiştirin ( "") IE. silin.

Ardından, istediğiniz herhangi bir ana bilgisayara aktarabilirsiniz.


0

Tüm nesnelerde benim için çalışan en basit normal ifade şudur:

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

Not quote-namesolmak zorunda TRUE(varsayılan olarak olan).

Yeni sürümlerde, --skip-definersürüm 5.7'de mysqlpump'ta tanıtılan anahtarın da mysqldump'a geldiğini umuyoruz.


0

Tüm satırları kaldırmak için PowerShell betiğini kullandım DEFINER:

get-içerik $ file_in_full_path | seç-dizgi-desen $ line_string_delete -notmatch | Out-File -width 1000000000 -Encoding $ file_out_full_path


0

Benim için hiçbir şey çalışmıyordu, bu yüzden kendi normal ifademi yazmam gerekiyordu.

  1. Veritabanınızı bir dosyaya, cattüm dosyaya ve grepgörmek için yalnızca tanımlayıcı ifadelerinize dökmeyi deneyin .

    cat dosya.sql | grep -o -E '. {, 60} TANIMLAYICI. {, 60}'

  2. Normal ifadenizi yazın

  3. Bu normal ifadeyle dökümünüzü sed'e aktarın. Örneğin benim beyanım:

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

  4. Kar!


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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.