AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 4129
Accepted
Zoredache
Zoredache
Asked: 2011-07-27 10:35:59 +0800 CST2011-07-27 10:35:59 +0800 CST 2011-07-27 10:35:59 +0800 CST

Modificar o DEFINER em muitas visualizações

  • 772

Estou tendo problemas para fazer backup de meus bancos de dados após uma atualização. Eu estive bisbilhotando no meu sistema tentando descobrir o porquê. Uma consulta que executei retornou esse resultado.

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

Após alguma investigação, parece que o definidor dessas visualizações é uma conta de desenvolvedor antiga que foi removida do sistema. Os bancos de dados e visualizações com esse problema são usados ​​com pouca frequência e a maioria é mantida para fins de arquivamento.

Existem cerca de 40 visualizações com um definidor que não existe mais. Existe uma maneira fácil de alterar o definidor para uma conta diferente em tudo de uma só vez? Existe uma maneira de fazer o mysqldump simplesmente despejar todas as visualizações em um arquivo para que eu possa editar esse arquivo e recriar as visualizações?

mysql view
  • 6 6 respostas
  • 69355 Views

6 respostas

  • Voted
  1. Derek Downey
    2011-07-27T11:05:54+08:002011-07-27T11:05:54+08:00

    Você pode usar ALTER VIEW em conjunto com o esquema de informações . Você mencionou despejá-lo em um arquivo de texto, então talvez algo assim:

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

    Misture isso com a linha de comando mysql (assumindo * nix, não familiarizado com o Windows):

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

    Nota lateral: Você não pode alterar as entradas information_schema diretamente . Nota2: Isso funciona para apenas um banco de dados por vez, se você deixar WHERE table_schema você precisa inserir comandos USE entre cada um.

    • 29
  2. Best Answer
    RolandoMySQLDBA
    2011-07-27T11:11:04+08:002011-07-27T11:11:04+08:00

    Crie um arquivo de texto com todas as definições de visualização:

    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
    

    Você edita AllMyViews.sql a partir daí. Em seguida, solte as visualizações

    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
    

    Depois de editar AllMyViews.sql, recarregue-os

    mysql -uusername -ppassword -A < AllMyViews.sql
    

    De uma chance !!!

    • 17
  3. Matija Nalis
    2016-05-20T18:00:38+08:002016-05-20T18:00:38+08:00

    Automatizando na solução do Derek, isso mudará o DEFINER para root@localhoste definirá SQL SECURITY INVOKER(certifique-se de que deseja isso primeiro!) em todas as visualizações em todos os bancos de dados:

    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
    

    AVISO: certifique-se de ter feito um backup completo do mysql (por exemplo, parando o mysqld e fazendo backup de todos os arquivos em /var/lib/mysql) antes de executá-lo - apenas no caso ... Funcionou para mim, mas YMMV .

    você também deve verificar todas as suas tabelas/visualizações com:

    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'
    

    ele não deve mais reclamar de definidores inválidos nas visualizações.

    • 4
  4. x-yuri
    2014-04-12T12:52:38+08:002014-04-12T12:52:38+08:00

    Exporte todas as visualizações do banco de dados <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
    

    ou:

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

    Edite views.sql(altere o definidor) e recrie-os:

    cat views.sql | mysql <DB>
    

    Especifique -ue -palterne se necessário.

    • 3
  5. Martin
    2020-03-25T09:04:01+08:002020-03-25T09:04:01+08:00

    Eu criei um script python simples que substitui o definidor de banco de dados de produção pelo definidor de banco de dados local. Este script modificará os arquivos de despejo e importará automaticamente os bancos de dados especificados.

    Repo GIT: https://github.com/mjakal/db-auto-import

    import getpass
    import os
    import time
    
    # Dump file path - here you can set your own path 
    dump_path = "./dumps/"
    # Set the list of dump file names to import
    dump_files = ["testing.sql"]
    # Set the list of definer names (inside dump file) you want to replace with your local db definer
    dump_definers = ["DEFINER=`prod`@`some-host.com`"]
    
    # MySQL local root username
    db_root_user = "root"
    # Set db names for each dump file - this must be in correct order
    db_names = ["testing"]
    
    # Local db user info
    db_user = "testing"
    db_password = "testing"
    db_host = "localhost"
    
    # Generate definer name from local db config - desired definer
    # You can hard-code this value if you wish 
    local_definer = f"DEFINER=`{db_user}`@`{db_host}`"
    
    # ------------------------------------------------------------------------------
    # You are all set - Leave the rest of the code as it is
    # ------------------------------------------------------------------------------
    
    # SQL connection config
    mysql_config = f"mysql -u {db_root_user}"
    
    
    def fix_dump_definer(dump_file):
        dump_file_path = dump_path + dump_file
    
        print("Fixing dump file:", dump_file)
    
        # Read file
        with open(dump_file_path, "rb") as file:
            file_data = file.read()
    
        # Replace the target string bytes
        for dump_definer in dump_definers:
            file_data = file_data.replace(dump_definer.encode(), local_definer.encode())
    
        # Write the file out again
        with open(dump_file_path, "wb") as file:
            file.write(file_data)
    
        print("Fixing dump file done:", dump_file)
    
    
    def create_db(db_name):
        drop_db = f"DROP DATABASE IF EXISTS {db_name};"
        recreate_db = f"CREATE DATABASE {db_name} CHARACTER SET utf8 COLLATE utf8_general_ci;"
        # default mysql
        grant_db_permissions = f"GRANT ALL PRIVILEGES ON {db_name}.* TO {db_user}@{db_host} IDENTIFIED BY {db_password};"
        # percona specific
        # grant_db_permissions = f"GRANT ALL PRIVILEGES ON {db_name}.* TO {db_user}@{db_host};"
        flush_db_privileges = "FLUSH PRIVILEGES;"
    
        recreate_db_queries = f'{mysql_config} -e "{drop_db}{recreate_db}{grant_db_permissions}{flush_db_privileges}"'
    
        print("Creating database:", db_name)
    
        os.system(recreate_db_queries)
    
        print("Await MySQL restart")
    
        time.sleep(10)
    
        print("Creating database done:", db_name)
    
    
    def import_db(db_name, dump_file):
        # Set dump file path
        dump_file_path = f"{dump_path}{dump_file}"
    
        print("Importing db:", db_name)
    
        import_db = f"{mysql_config} {db_name} < {dump_file_path}"
    
        os.system(import_db)
    
        time.sleep(5)
    
        print("Import done:", db_name)
    
    
    def manage_db_import(db_name, dump_file):
        fix_dump_definer(dump_file)
        create_db(db_name)
        import_db(db_name, dump_file)
    
    
    def main_script():
        try:
            print("--------------------------------------------------------------------------------")
            print("WARNING - This script is used for development purposes only.")
            print("Please don't try roning it on production environment!")
            print("--------------------------------------------------------------------------------")
    
            # Get db_names and dump_files list length
            db_count = len(db_names)
            dump_count = len(dump_files)
    
            # Check if lists have the same length
            if db_count != dump_count:
                return "db_names and dump_files must have the same length."
    
            # e.g. db_count = 11 result will be 100 - 1
            import_all_option = (10 ** ((db_count // 10) + 1)) - 1
    
            print("Please select one of the options below:")
    
            for index, dump_file in enumerate(dump_files):
                db_name = db_names[index]
    
                print(f"{index} - Import {db_name}")
    
            print(f"{import_all_option} - Import all databases")
            print(f"{import_all_option + 1} - Exit script")
    
            selected_option = int(input("Select option: "))
    
            # Exit the script
            if selected_option == import_all_option + 1:
                return "Exiting script."
    
            # Input MySQL root password
            db_root_password = getpass.getpass(prompt="Enter MySQL root password: ", stream=None)
    
            # If password exists, modify mysql_config global variable
            if db_root_password:
                global mysql_config
                mysql_config = f"{mysql_config} -p{db_root_password}"
    
            print("If you continue with this operation existing database(s) will be deleted.")
            continue_import = input("Would you like to continue (y/n)? ")
    
            if continue_import != "y":
                return "Exiting script."
    
            if selected_option == import_all_option:
                print("Importing all databases please wait...")
    
                for index, dump_file in enumerate(dump_files):
                    db_name = db_names[index]
    
                    manage_db_import(db_name, dump_file)
            elif selected_option in range(0, db_count):
                db_name = db_names[selected_option]
                dump_file = dump_files[selected_option]
    
                print(f"Importing {db_name} please wait...")
    
                manage_db_import(db_name, dump_file)
            else:
                return "Invalid input, exiting script."
    
            return "DB import finished."
        except Exception as ex:
            print(str(ex))
            return "Something went wrong, exiting script."
    
    
    # Call the main function
    main_script_output = main_script()
    
    print(main_script_output)
    

    Script de importação automática de banco de dados

    Este script resolve o problema do definidor de usuário ao importar bancos de dados de um servidor sql para outro (por exemplo, servidor de produção para servidor de desenvolvimento local). Ele modifica a entrada do definidor do usuário em todas as visualizações/procedimentos armazenados dentro dos arquivos de despejo sql. Depois de modificar o definidor, ele importará automaticamente os bancos de dados especificados.

    Requisitos

    • SO - Linux/MacOS
    • Python >= 3,6
    • MySQL, MariaDB ou Percona

    NOTA - Se você estiver usando Percona, comente a linha 58 e descomente a linha 60

    # default mysql
    # grant_db_permissions = f"GRANT ALL PRIVILEGES ON {db_name}.* TO {db_user}@{db_host} IDENTIFIED BY {db_password};"
    # percona specific
    grant_db_permissions = f"GRANT ALL PRIVILEGES ON {db_name}.* TO {db_user}@{db_host};"
    

    Configuração

    Abra o script db_auto_import.py em seu editor de texto favorito e edite as linhas abaixo.

    # Dump file path - here you can set your own path 
    dump_path = "./dumps/"
    # Set the list of dump file names to import
    dump_files = ["testing.sql"]
    # Set the list of definer names (inside dump file) you want to replace with your local db definer
    dump_definers = ["DEFINER=`prod`@`some-host.com`"]
    
    # MySQL local root username
    db_root_user = "root"
    # Set db names for each dump file - this must be in correct order
    db_names = ["testing"]
    
    # Local db user info
    db_user = "testing"
    db_password = "testing"
    db_host = "localhost"
    

    Como executar o script

    Primeiro, precisamos copiar/colar todos os arquivos de despejo de produção na pasta /dumps/. Os nomes dos arquivos de despejo devem corresponder aos nomes especificados na lista dump_files. Verifique sua configuração e execute o comando abaixo.

    python db_auto_import.py
    
    • -1
  6. Ritikesh
    2021-08-14T21:45:57+08:002021-08-14T21:45:57+08:00

    solução:

    1. no phpmyadmin vá em "database_name" clique nas opções do menu de alternância acima dos gatilhos.
    2. procure a respectiva tabela da qual você deseja alterar o definidor.
    3. vá para a opção de edição e, em seguida, role para baixo até a opção de definição abaixo.
    4. mude o definidor para "o que você quiser".
    • -2

relate perguntas

  • Existem ferramentas de benchmarking do MySQL? [fechado]

  • Onde posso encontrar o log lento do mysql?

  • Como posso otimizar um mysqldump de um banco de dados grande?

  • Quando é o momento certo para usar o MariaDB em vez do MySQL e por quê?

  • Como um grupo pode rastrear alterações no esquema do banco de dados?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Como você mostra o SQL em execução em um banco de dados Oracle?

    • 2 respostas
  • Marko Smith

    Como selecionar a primeira linha de cada grupo?

    • 6 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Posso ver Consultas Históricas executadas em um banco de dados SQL Server?

    • 6 respostas
  • Marko Smith

    Como uso currval() no PostgreSQL para obter o último id inserido?

    • 10 respostas
  • Marko Smith

    Como executar o psql no Mac OS X?

    • 11 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Marko Smith

    Passando parâmetros de array para um procedimento armazenado

    • 12 respostas
  • Martin Hope
    Manuel Leduc Restrição exclusiva de várias colunas do PostgreSQL e valores NULL 2011-12-28 01:10:21 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Stuart Blackler Quando uma chave primária deve ser declarada sem cluster? 2011-11-11 13:31:59 +0800 CST
  • Martin Hope
    pedrosanta Listar os privilégios do banco de dados usando o psql 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST
  • Martin Hope
    BrunoLM Guid vs INT - Qual é melhor como chave primária? 2011-01-05 23:46:34 +0800 CST
  • Martin Hope
    bernd_k Quando devo usar uma restrição exclusiva em vez de um índice exclusivo? 2011-01-05 02:32:27 +0800 CST
  • Martin Hope
    Patrick Como posso otimizar um mysqldump de um banco de dados grande? 2011-01-04 13:13:48 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve