Ayrıcalıkları MySQL'den dışa aktarabilir ve ardından yeni bir sunucuya nasıl aktarabilirim?


88

Mysqldump kullanarak veritabanlarının nasıl alınacağını / alınacağını biliyorum.

Ekstra puan için, yeni veritabanında zaten mevcut olan birkaç veritabanı var, eski sunucu ayrıcalıklarını var olan çifti çekmeden nasıl alabilirim.

Eski sunucu: 5.0.67 topluluk

Yeni sunucu: 5.0.51a-24 + lenny1

EDIT: Eski Sunucu'dan db 'mysql' dökümü yaptım ve şimdi Yeni Sunucudaki 'mysql' db ile birleşmenin doğru yolunu bilmek istiyorum.

PhpMyAdmin'i kullanarak düz bir 'Import' (Deneme) denedim ve yinelemeyle ilgili bir hatayla karşılaştım (zaten manuel olarak geçirdiğim).

İki 'MySQL' veritabanını birleştirmenin zarif bir yolu var mı?


1. PHPMyAdmin'i kullanmanız bir zorunluluk mu? Eğer öyleyse, sizin için bazı PHPMyAdmin'e özel talimatlar yazacağım. 2. Eğer "mysql.user limit 1; 'den * seçmeyi" denerseniz PHPMyAdmin'den sonuç veya hata alıyor musunuz?
Bruno Bronosky

1
Aşağıda bahsettiğim gibi, Richard'ın göçmen senaryosunun hibe bilgisi almak için iyi bir yol olduğunu düşünüyorum. Ancak, zaten var olan kullanıcılar için kullanıcı tablosuna INSERT'leri yorumlamak üzere döküm dosyasını düzenlemeyi deneyebilirsiniz. Eski sunucudan geri yüklenen dbs için ayrıcalıklar kopyalanacaktır. Yeni kutuya geri yüklediğiniz dbs'lerin bazıları için zaten el ile ayrıcalıklar atadıysanız, ayrıcalık dosyalarında bu tablo adlarını arayın ve bunları da yorumlayın. Daha sonra bir floş_privilegesini unutmayın. Mysql db'nin iyi tanımı: grahamwideman.com/gw/tech/mysql/perms/index.htm
nedm

Yanıtlar:


169

MySQL db ile karışıklık etmeyin. Orada sadece kullanıcılar tablosundan çok daha fazlası var. En iyi bahis, " BEDAVA KARŞI GÖSTER " komutudur. .Bashrc'imde (aslında benim .bashrc'de kaynak yaptığım .bash_aliases) bir sürü CLI bakım takma adı ve işlevi var. Bu işlev:

mygrants()
{
  mysql -B -N $@ -e "SELECT DISTINCT CONCAT(
    'SHOW GRANTS FOR \'', user, '\'@\'', host, '\';'
    ) AS query FROM mysql.user" | \
  mysql $@ | \
  sed 's/\(GRANT .*\)/\1;/;s/^\(Grants for .*\)/## \1 ##/;/##/{x;p;x;}'
}

İlk mysql komutu, ikinci mysql komutuna aktarılan geçerli SQL'yi üretmek için SQL kullanır. Çıktı daha sonra güzel yorumlar eklemek için sed ile birleştirilir.

Komuttaki $ @, şu şekilde çağırmanıza izin verecektir: mygrants --host = prod-db1 - kullanıcı = admin --password = gizli

Tam unix araç kitinizi aşağıdaki şekilde kullanabilirsiniz:

mygrants --host=prod-db1 --user=admin --password=secret | grep rails_admin | mysql --host=staging-db1 --user=admin --password=secret

Kullanıcıları taşımak için doğru yol budur. MySQL ACL'niz saf SQL ile değiştirildi.


Bu aslında harika çalışan hoş bir bash yardımcı fonksiyonudur. Bundan çıktısını alın ve yeni sunucuda çalışabilmeniz için ayrıcalıklar doğru ve doğru bir şekilde girildi.
Jeremy Bouse

1
İşlevini seviyorum, bugün beni çok iş kurtardı. Teşekkür ederim, teşekkür ederim, teşekkür ederim ...
Fabio

2
Bu harika ama büyük bir kusuru var. Veritabanı adlarındaki alt çizgilere fazladan "\" eklenir, bu nedenle, örneğin foo_bar adlı bir veritabanında belirli yetkilere sahip bir kullanıcı varsa, doğru alınmayacak şekilde foo_bar yerine foo \ _bar olarak gösterilecektir. . En azından, çıktıyı sizden bir SQL dosyasına kaydederseniz ve ardından yeni sunucuya alırsanız bu olur. Doğrudan ihracat ve ithalat borularını tek bir hatta denemedim.
matteo

1
Bu emre dikkat edin. userMasada ana bilgisayarı %olan bir kullanıcı varsa , ancak dbtabloda hostaçık bir değer olan girişleriniz varsa, dbtablodaki bu girişler bu yöntem kullanılarak alınmaz.
Mitar

1
@ matteo İşlevdeki -r2. mysql komutuna ekleyin , çift çıkışlar çıkış yapmayacaktır mysql. örneğin:mysql -r $@
lifo

45

MySQL Örneğindeki SQL Grants'ı çıkarmak için iki yöntem vardır.

YÖNTEM 1

Sen kullanabilirsiniz pt-show-hibe Percona Toolkit dan

MYSQL_CONN="-uroot -ppassword"
pt-show-grants ${MYSQL_CONN} > MySQLUserGrants.sql

YÖNTEM # 2

pt-show-grantsAşağıdaki ile taklit edebilirsiniz

MYSQL_CONN="-uroot -ppassword"
mysql ${MYSQL_CONN} --skip-column-names -A -e"SELECT CONCAT('SHOW GRANTS FOR ''',user,'''@''',host,''';') FROM mysql.user WHERE user<>''" | mysql ${MYSQL_CONN} --skip-column-names -A | sed 's/$/;/g' > MySQLUserGrants.sql

Her iki yöntem de MySQL hibelerinin saf bir SQL dökümü üretecektir. Yapmanız gereken tek şey betiği yeni bir sunucuda çalıştırmak:

mysql -uroot -p -A < MySQLUserGrants.sql

Bir şans ver !!!


1
pt-show-gnts tam da bunun için istediğin şey, harika çalışıyor.
Glenn Plas,

Percona sadece saf bir kadınlıktır.
sjas,

7
Fakat cevap # 2 de aynı derecede iyi ve ek bir yazılıma gerek kalmadan çalışacak!
sjas,

14

Richard Bronosky'nin cevabı benim için son derece yararlı oldu. Çok teşekkürler!!!

İşte benim için yararlı olan küçük bir varyasyon. Örneğin, phpmyadmin çalıştıran iki Ubuntu kurulumu arasında kullanıcıları aktarmak için faydalıdır. Sadece tüm kullanıcılar için root, phpmyadmin ve debian-sys-maint ayrıcalıklarını at. Kod o zaman

mygrants()
{
mysql -B -N $@ -e "SELECT DISTINCT CONCAT(
'SHOW GRANTS FOR ''', user, '''@''', host, ''';'
) AS query FROM mysql.user WHERE user NOT IN ('root','phpmyadmin','debian-sys-maint')"  | \
mysql $@ | \
sed 's/\(GRANT .*\)/\1;/;s/^\(Grants for .*\)/## \1 ##/;/##/{x;p;x;}'
}

2
Benim grep rails_adminörneğime bakarsanız, bunu her kenar kasası için özel bir işlev yapmadan nasıl yapacağımı öğrenebilirsiniz. Grep's "invert-match" seçeneğini şu şekilde kullanın:mygrants --host=prod-db1 --user=admin --password=secret | grep -Ev 'root|phpmyadmin|debian-sys-maint' | mysql --host=staging-db1 --user=admin --password=secret
Bruno Bronosky

7

Veya, percona-toolkit'i (eski maatkit) kullanın ve bu amaçla kullanın pt-show-grants(veya mk-show-grants). Hantal komut dosyaları ve / veya saklı yordamlar için gerek yok.


5

'Mysql' veritabanını mysqldump ile yenisine alabilirsiniz; Bir flush_privileges veya yeniden başlatma gerekli olacak ve kesinlikle önce mevcut mysq db'yi yedeklemek isteyeceksiniz.

Mevcut ayrıcalıklarınızı kaldırmaktan kaçınmak için, ayrıcalık tablolarındaki (db, column_priv, host, func, vb.) Satırların yerine eklemek istediğinize emin olun.


@Nedm teşekkürler. Görünüşe göre can sıkıcı cPanel server dbs almaya çalışıyorum db 'mysql' göstermiyor. Aksi takdirde cevabınızı test eder ve onaylarım. Bunu çözdüğümde kontrol edeceğim. Teşekkürler.
Gareth

Bu talihsiz ancak anlaşılabilir bir durumdur, muhtemelen doğrudan paylaşılan bir db'de doğrudan kullanıcı tarafından sahip olunan veritabanına erişiminiz engellenir.
Dave Cheney

Evet, 'mysql' erişimi olmadan, kullanıcılar veya izinlerle ilgili herhangi bir şey yapmak zor olacaktır. Komut satırı erişiminiz var mı? Mysqldump'ı terminalden veya komut satırından çalıştırabilir misiniz (mysql kabuğundan DEĞİL)? mysqldump -u kullanıcı adı -ppassword mysql> mysqldump.sql
nedm

Eğer 'root' olarak giriş yapmışsam db 'mysql' ye Cpanel WHM'den erişilebilir. Oradan izinleri içeren 'mysql' veritabanına sahip phpmyadmin sürümüne erişebilirim
Gareth

Var olan bir mysql şemasına birleştirmek, bir mysql şemadan mysqldump aracılığıyla çıkarılan verilerin neredeyse sorunlu olduğu kesindir. Zorunlu ilişkiler, vb. İle karmaşık bir şema değiştiriyorsunuz. Bu şema o kadar karmaşık ki, aslında onunla başa çıkmak için özel SQL sözdizimi (GRANT, REVOKE, DROP USER, vb.) Oluşturdular. Bununla birlikte, özetiniz yalnızca INSERT ifadelerinden oluşur. Burada karakter tükeniyor. Devam edeyim mi
Bruno Bronosky

4

Saklı yordam olarak da yapabilirsiniz:

CREATE PROCEDURE spShowGrants()
    READS SQL DATA
    COMMENT 'Show GRANT statements for users'
BEGIN
    DECLARE v VARCHAR(64) CHARACTER SET utf8;
    DECLARE c CURSOR FOR
    SELECT DISTINCT CONCAT(
        'SHOW GRANTS FOR ', user, '@', host, ';'
    ) AS query FROM mysql.user;
    DECLARE EXIT HANDLER FOR NOT FOUND BEGIN END;  
    OPEN c;
    WHILE TRUE DO
        FETCH c INTO v;
        SET @v = v;
        PREPARE stmt FROM @v;
        EXECUTE stmt;
    END WHILE;
    CLOSE c;
END

ve ara

$ mysql -p -e "CALL spShowGrants" mysql

daha sonra ayrıcalıkların bir yedeğini almak için çıktıyı Richards sed komutundan geçirin.


3

Görünüşe göre @Richard Bronosky'nin cevabı doğru olsa da, bir dizi veritabanını bir sunucudan diğerine taşımaya çalıştıktan sonra bu soruyla karşılaştım ve çözüm çok daha kolaydı:

server1$ mysqldump -u root -p --all-databases > dbdump.sql

server2$ mysql -u root -p < dbdump.sql

Bu noktada, oturum açtıysam tüm verilerim görülebilirdi root, mysql.usertablonun içinde beklediğim her şey vardı, fakat diğer kullanıcıların hiçbiri olarak giriş yapamadım ve tekrar sormam gerektiğini varsayarak bu soruyu buldum. GRANTifadeleri yayınlayın .

Bununla birlikte, mysql.*tablolardaki güncellenmiş ayrıcalıkların geçerli olabilmesi için mysql sunucusunun basitçe yeniden başlatılması gerektiği ortaya çıktı :

server2$ sudo restart mysql

Umarım bu başkasının basit bir iş ne olması gerektiğini başarmasına yardımcı olur!


Oh, ve durumum OP'lerden biraz farklıydı, çünkü mevcut veritabanları / kullanıcıları ile bir sunucuya bir dökümü birleştirmeye çalışmıyorum.
Tom

2
'Ayrıcalıkları güncellemek' için MySQLd'yi yeniden başlatmanız gerekmez. MySQL komutu ile 'ayrıcalıkları temizle';
CloudWeavers

Bu yaklaşımla ilgili sorun, yalnızca hem kaynak hem de hedef MySQL sürümleri aynı olduğunda işe yaramasıdır. Aksi takdirde, örneğin kaynak mysql.user tablosu hedef mysql.user tablosundan farklı sütunlara sahip olduğu için sorunlarınız olabilir.
Mitar

3

PHP betiğine ne dersin? :)

Bu komut dosyasında kaynağı görüntülemek ve listelenen tüm yetkilere sahip olacaksınız:

//connect
mysql_select_db("mysql", mysql_connect("localhost","root",""));

//create grants select statements
$rs = mysql_query("SELECT DISTINCT CONCAT('SHOW GRANTS FOR ''', user, '''@''', host, ''';') AS query FROM user");

//iterate through grants
while ($row=mysql_fetch_array($rs)) {
    //run grant query
    $rs2 = mysql_query($row['query']);
    //iterate through results
    while($row2 = mysql_fetch_array($rs2)){
        //print results
        echo $row2[0] . ";\n\n";
    }
}

2

aşağıdaki kod ile bir kabuk betiği dosyası oluşturun:

############################################## 3
echo "SELECT DISTINCT CONCAT (\"show grants for '\", user, \"'@'\", host, \"';\") AS query FROM mysql.user; " >   script.sql    
echo "*** You will be asked to enter the root password twice ******"    
mysql -u root -p  < script.sql > output.sql ;    
cat output.sql | grep show > output1.sql  ; rm output.sql -f ; 
mysql -u root -p  < output1.sql > output.sql ;
clear
echo "-----Exported Grants-----"    
cat  output.sql ; rm  output.sql   output1.sql -f    
echo "-------------------------"
rm  script.sql -f
#

**** daha sonra bu şekilde kabukta çalıştırın: iki kez root şifresini girmeniz istenecek ve daha sonra GRANTS SQL ekranda görünecektir. ****


0

One-liner hemen hemen aynı şeyi yapıyor pt-show-grants:

mysql --skip-column-names -A -e"SELECT CONCAT('SHOW GRANTS FOR ''',user,'''@''',host,''';') FROM mysql.user WHERE user<>''" | mysql --skip-column-names -A | sed 's/$/;/g'

Yalnızca unix araçlarına dayanarak, ek bir yazılıma gerek yoktur.

Bir bash kabuğunun içinden yürütmek, kullanıcı .my.cnfşifrenizin mysql rootokunabileceği bir çalışmanız olduğunu varsayar .


@rolandomysqldba'nın gönderisinin yarısını, yarım yıl sonra geri geldikten sonra çoğalttım.
sjas
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.