Як я можу експортувати привілеї з MySQL, а потім імпортувати на новий сервер?


88

Я знаю, як експортувати / імпортувати бази даних за допомогою mysqldump, і це добре, але як отримати привілеї на новий сервер.

Для додаткових балів є вже кілька існуючих баз даних на новій, як я імпортую привілеї старих серверів, не занурюючи пару існуючих.

Старий сервер: 5.0.67-спільнота

Новий сервер: 5.0.51a-24 + lenny1

EDIT: У мене є дамп db 'mysql' зі Старого сервера, і тепер я хочу знати правильний спосіб об’єднання з 'mysql' db на Новому сервері.

Я спробував "Імпорт" прямо за допомогою phpMyAdmin, і в результаті виявилася помилка щодо дубліката (ту, яку я вже перемістив вручну).

У когось елегантний спосіб об’єднання двох баз даних mysql?


1. Чи є вимогою до вас використовувати PHPMyAdmin? Якщо це так, я напишу вам кілька конкретних інструкцій PHPMyAdmin. 2. Від PHPMyAdmin, якщо ви намагаєтесь "вибрати * з mysql.user межа 1;" чи отримуєте ви результат чи помилку
Бруно Броноський,

1
Як я вже згадував нижче, я вважаю, що сценарій мігрантів Річарда - це хороший спосіб отримати інформацію про грант. Однак ви можете також спробувати відредагувати файл дампа, щоб прокоментувати INSERT в таблицю користувачів для користувачів, які вже існують. Привілеї для dbs, відновлених зі старого сервера, будуть скопійовані. Якщо ви вже призначили привілеї вручну для деяких даних, які ви відновили у новому полі, знайдіть ці назви таблиць у файлах привілеїв та також прокоментуйте їх. Не забудьте пізніше привілей. Хороший опис mysql db за адресою: grahamwideman.com/gw/tech/mysql/perms/index.htm
неділь

Відповіді:


169

Не возиться з mysql db. Там відбувається набагато більше, ніж просто таблиця користувачів. Ваша найкраща ставка - команда " ПОКАЗАТИ ГРАНТИ ДЛЯ". У мене є багато псевдонімів та функцій технічного обслуговування CLI в моєму .bashrc (власне, моєму .bash_aliases, яке я надсилаю у своєму .bashrc). Ця функція:

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;}'
}

Перша команда mysql використовує SQL для генерування дійсного SQL, який передається на другу команду mysql. Потім висновок проводиться через sed, щоб додавати гарні коментарі.

Команда $ @ дозволить вам викликати її як: mygrants --host = prod-db1 --user = admin --password = secret

Ви можете використовувати повний набір інструментів Unix для цього подібного:

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

Це правильний спосіб переміщення користувачів. Ваш ACL MySQL модифікований із чистим SQL.


Це насправді приємна функція помічника баш, яка чудово працює. Візьміть висновок з цього і зможете запустити на новому сервері, і привілеї будуть введені правильно та точно.
Джеремі Бууз

1
Я люблю вашу функцію, сьогодні це врятувало мені багато роботи. Дякую, дякую, дякую ...
Фабіо

2
Це чудово, але він має один великий недолік. Додатковий знак "\" додається до підкреслення у назвах баз даних, тому, якщо у вас є, наприклад, користувач із певними привілеями в базі даних під назвою foo_bar, він буде відображатися як foo \ _bar замість foo_bar, так що він не буде імпортований правильно . Принаймні, це станеться, якщо ви збережете вихідний файл зі свого сценарію у файл SQL і потім імпортуєте його на новий сервер. Я не пробував прямих трубопроводів експорту та імпорту в одному рядку.
Маттео

1
Будьте обережні з цією командою. Якщо у userтаблиці є користувач з хостом %, але потім у dbтаблиці ви маєте записи, де hostє явне значення, ці записи в dbтаблиці не будуть отримані за допомогою цього методу.
Мітар

1
@matteo Додати -rдо другої команди mysql у функції, і подвійні втечі не будуть виведені mysql. напр .:mysql -r $@
lifo

45

Існує два способи отримання грантів SQL з екземпляра MySQL

МЕТОД №1

Ви можете використовувати pt-show-гранти від Percona Toolkit

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

МЕТОД №2

Можна наслідувати pt-show-grantsнаступним чином

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

Будь-який метод створить чистий дамп SQL грантів MySQL. Залишилося лише виконати скрипт на новому сервері:

mysql -uroot -p -A < MySQLUserGrants.sql

Спробувати !!!


1
pt-show-grant - це саме те, що ви хочете для цього, це чудово працює.
Гленн Плаз

Перкона - це просто чиста дивовижність.
sjas

7
Але відповідь №2 так само хороша і працюватиме без додаткового програмного забезпечення!
sjas

14

Відповідь Річарда Броноського була для мене надзвичайно корисною. Дуже дякую!!!

Ось невеликий варіант, який був корисним для мене. Це корисно для передачі користувачів, наприклад, між двома установками Ubuntu під управлінням phpmyadmin. Просто вивантажте права доступу для всіх користувачів, крім root, phpmyadmin та debian-sys-maint. Код тоді

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
Якщо ви подивитесь на мій приклад, де я grep rails_adminможу зробити висновок, як це зробити, не роблячи спеціальної функції для кожного крайового випадку. Використовуйте опцію " mygrants --host=prod-db1 --user=admin --password=secret | grep -Ev 'root|phpmyadmin|debian-sys-maint' | mysql --host=staging-db1 --user=admin --password=secret
обернутий

7

Або використовуйте інструмент інструментів percona (колишній maatkit) і використовуйте pt-show-grants(або mk-show-grants) для цієї мети. Не потрібно громіздких сценаріїв та / або збережених процедур.


5

Ви можете mysqldump 'mysql' базу даних та імпортувати до нової; буде потрібен flush_privileges або перезапуск, і ви обов'язково спочатку захочете створити резервну копію існуючого mysq db.

Щоб уникнути видалення існуючих привілеїв, не забудьте додати рядки в таблиці привілеїв, а не замінювати їх (db, column_priv, хост, func тощо).


Дякую @nedm. Схоже, дратуючий сервер cPanel, який я намагаюся зняти, не показує db 'mysql'. Інакше я би перевірив і підтвердив вашу відповідь. Як тільки я зрозумію, я перевірю. Дякую.
Гарет

Це прикро, але зрозуміло, що вам, мабуть, заборонено отримувати доступ до будь-якої бази даних, окрім тієї, що безпосередньо належить вашому користувачеві на спільному DB.
Дейв Чейні

Так, без доступу до "mysql" буде важко зробити щось, що стосується користувачів або дозволів. У вас є доступ до командного рядка? Чи можете ви запустити mysqldump з терміналу чи командного рядка (НЕ з оболонки mysql)? mysqldump -u ім'я користувача -ppassword mysql> mysqldump.sql
неділь

Db 'mysql' був доступний у WHM Cpanel, якщо я ввійшов як "root". Звідти я можу отримати доступ до версії phpmyadmin, в якій є база даних "mysql", що містить дозволи
Гарет

Об’єднання в існуючу схему mysql, дані, витягнуті зі схеми mysql через mysqldump, майже напевно є проблематичними. Ви маніпулюєте складною схемою з примусовими відносинами і т. Д. Ця схема є настільки складною, що вони створили виділений синтаксис SQL (GRANT, REVOKE, DROP USER тощо) для роботи з ним. Однак ваш витяг складається лише з тверджень INSERT. У мене тут не вистачає персонажів. Потрібно продовжувати?
Бруно Броноський,

4

Ви також можете зробити це як збережена процедура:

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

і зателефонуйте за допомогою

$ mysql -p -e "CALL spShowGrants" mysql

потім передайте вихід через команду Richards sed, щоб отримати резервну копію привілеїв.


3

Незважаючи на те, що відповідь @Richard Bronosky є правильною, я натрапив на це питання, намагаючись перенести набір баз даних з одного сервера на інший, і рішення було набагато простішим:

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

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

У цей момент усі мої дані були помітні, якщо я входив як root, у mysql.userтаблиці було все, що я очікував, але я не зміг увійти як будь-хто з інших користувачів, і я знайшов це питання, припускаючи, що мені доведеться повторно видавати GRANTзаяви.

Однак виявляється, що сервер mysql просто потрібно було перезапустити, щоб оновлені привілеї в mysql.*таблицях набули чинності:

server2$ sudo restart mysql

Сподіваємось, це допомагає комусь іншому досягти того, що має бути простим завданням!


О, і моя ситуація була дещо іншою, ніж ОП, тим, що я не намагався об'єднати дамп у сервер із існуючими базами даних / користувачами.
Том

2
Вам фактично не потрібно перезавантажувати MySQLd для "оновлення привілеїв". Це можна зробити за допомогою команди MySQL "flush privileges;"
CloudWeavers

Проблема такого підходу полягає в тому, що він працює лише тоді, коли і вихідна, і цільова версія MySQL однакові. В іншому випадку у вас можуть виникнути проблеми, оскільки, наприклад, таблиця mysql.user має різні стовпці, ніж таблиця mysql.user.
Мітар

3

Як щодо сценарію PHP? :)

Перегляньте джерело цього сценарію, і ви отримаєте всі перелічені привілеї:

//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

створити файл сценарію оболонки із таким кодом:

################################################### 3 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
#

****, тоді запустіть його на оболонці так: вам буде запропоновано ввести кореневий пароль двічі, і тоді на екрані відобразиться GRANTS SQL. ****


0

Один лайнер робить майже те саме, що і дивовижний 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'

На основі лише інструментів Unix, додаткове програмне забезпечення не потрібно.

Виконати з оболонки bash, припускаючи, що у вас є робота, .my.cnfде mysql rootможна прочитати пароль вашого користувача.


Я повторив половину поста @rolandomysqldba після повернення через півроку, я щойно зрозумів.
sjas
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.