importing mysql structures only or restore ignoring non-existing tables and columns? - mysql

I have 2 servers (1 for development, 1 for service)
I keep ADD/DELETE columns and CREATE/DELETE Indexes on my development server, so these 2 server have similar but different mysql data structures.
I know there's an option to expert structures only. (like –no-data)
Is there a way (except 3rd party software like mysqldiff.org) to import structure only to an existing data?
Alternativley, is there a way to import only data ignoring non-existing tables and colums?
(I thought this may do the trick if I back-up data -> import structure -> restore the data.)
thanks in advance

I had exactly the same problem. I solved it like this:
Like you already mentioned:
back-up data -> import structure -> restore the data as follows
#DEVELOPEMENT (export structure only)<br/>
**mysqldump -u user -p –d test > structure-only.sql**
#DEPLOYMENT (export data only)<br/>
**mysqldump -u user -p -t -c test > data-only.sql**
#DEPLOYMENT (import structure only)<br/>
**mysql -u user -p test < structure-only.sql**
#DEPLOYMENT (import data only)<br/>
**mysql -u user -p test < data-only.sql**
The trick that made it work for me was the -c switch on the second export (this way full column names are used, and there are no 'column count' errors when you import it back in the new structure).

Related

How to create a file name using MySQL or batch file where part of the file contents need to be in the name?

OK, here is what I am trying to.
Using MySQL command line, I am running a script and then saving out the data like this:
mysql -h DATABASE -u yyyy -pxxxx < E:/Step_2.sql > E:/OUTPUT_YYYY_QQ.csv
Now, either using MySQL or a Windows batch command, I want the YYYY and QQ to be a specific value. It isn't the current date though. In this example, I want the YYYY to be 2017 and the QQ to be Q4.
I have flexibility to either:
Create a new table in SQL with the values in it if needed. Then with help run a command to use those values as part of the file name.
Or I can place a file on the server somewhere to "reference" in order to grab the data and place it in the file name.
Any thoughts?
Here I have created a shell script called "test.sh", which will generate the file name dynamically, but all you need to convert this shell script into windows batch. It's an idea to you as per your comment.
test.sh
file_name=$(mysql -N -hlocalhost -uvivek -pvivek -e "select concat('OUTPUT_',year(date_column),'_Q',quarter(date_column),'.csv') file_name from table_name")
mysql -hlocalhost -uvivek -pvivek </home/vivekanand/vivek/stack/test.sql >/home/vivekanand/vivek/stack/$file_name
After running the script, I got file created as below with correct output of SQL file "test.sql"
-rw-rw-r-- 1 vivekanand vivekanand 14535 May 7 13:56 OUTPUT_2017_Q4.csv

How GreenPlum implements external table?

I am learning gpdb. And I am confused on external tables. Following is my understanding.
For Read-only table, gpdb only create metadata of the table. All data is stored on remote server like hdfs. When querying, data is transferred from remote server to segment. Data will not be saved on segments when query ends.
For Write-only table, gpdb will load data from remote. All data will be saved on segments. Insert action will modify data on local segment, not remote.
Is my understanding right?
An External Table is a table where the data is stored and managed outside of the database. An example would be a CSV or TEXT file.
A Readable External Table has the metadata stored in the database and like you said, all data is stored somewhere else like HDFS. It can also be the local filesystem to Greenplum. The most common External Table uses gpfdist to "serve" the file(s). gpfdist is basically a web server that multiple segments can read at the same time.
Example:
First, I will start gpfdist on four different hosts. These hosts must be accessible by all segment hosts too.
[gpadmin#host1] gpfdist -p 8999 -d /landing/ &
[gpadmin#host2] gpfdist -p 8999 -d /landing/ &
[gpadmin#host3] gpfdist -p 8999 -d /landing/ &
[gpadmin#host4] gpfdist -p 8999 -d /landing/ &
And now put an example file in each:
[gpadmin#host1] hostname > /landing/hostname.txt
[gpadmin#host2] hostname > /landing/hostname.txt
[gpadmin#host3] hostname > /landing/hostname.txt
[gpadmin#host4] hostname > /landing/hostname.txt
Create an External Table to read it:
[gpadmin#master] psql
gpadmin=# create external table public.ext_hostnames
(hostname text)
location (
'gpfdist://host1:8999/hostname.txt',
'gpfdist://host2:8999/hostname.txt',
'gpfdist://host3:8999/hostname.txt',
'gpfdist://host4:8999/hostname.txt')
format 'text' (delimiter '|' null as '');
This simple example shows files managed outside of the database that are now accessible by Greenplum with an External Table.
A Writable External Table reverses this and allows you to write data to an external system like HDFS or the posix filesystem.
[gpadmin#master] gpfdist -p 8999 -d /home/gpadmin/ &
[gpadmin#master] psql
gpadmin=# create writable external table public.wrt_example
(foo text)
location ('gpfdist://master:8999/foo.txt')
format 'text' (delimiter '|' null as '');
insert into public.wrt_example values ('jon');
gpadmin=# insert into public.wrt_example select 'jon';
gpadmin=# \q
[gpadmin#master] cat /home/gpadmin/foot.txt
jon
The use case for a Writable External Table is to take data in Greenplum and put it somewhere else.
A common example is when you use HDFS for a Data Lake and Greenplum for Analytics. You could read data out of HDFS with an External Table and INSERT it into Greenplum tables. You then analyze this data, use analytical functions from the Madlib package, and find new insights about your data. Now you want to push this new data from Greenplum back to HDFS so that other consumers can benefit from the insights. You then use a Writable External Table to INSERT the data from Greenplum to HDFS.
The most common use case for a Readable External Table is loading files from external sources into Greenplum.

Import MySQL DB Schema

I have successfully used mysqldump to export a db schema without data. I now want to import this db schema.
I have tried a couple of methods but come across the error related to the < character.
Any ideas?
As the error shows, input redirection in PowerShell does not work with the <sign. You would do it using the Cmdlet Get-Content and use piping to put the output into the input of the command:
Get-Content v:\mcsdb.sql | mysql -u root --sql --recreate-schema mcs
If you are interested in more in-depth info, refer to the Documentation.

Update automatic attributes in Opscode Chef (serialized_object)

I had a couple of nodes in my chef server that had a problem while bootstrapping and missed the FQDN and domain automatic attributes due to which they were not indexed by SOLR and not searchable by knife. I could not rebootstrap these machines, but wanted to fix this and it took me a while to do so. Therefore I am posting this hoping that it will save others some time.
Automatic attributes are stored by Chef in the database and are not editable by knife (see Chef Attributes Overview). They are stored in chef's database as a column named serialized_object in the nodes table in hex and is in fact a gzipped JSON string.
To obtain the JSON string:
Use a PostgreSQL client to connect to the chef PostgreSQL (you can find the credentials on the chef server in /etc/chef-server/chef-server-secrets.json)
Save the contents of the serialized_object to a file say serialized_object.hex (it should look something like '\x1f8b08000...')
Run: xxd -p -r serialized_object.hex > serialized_object.gz
Run: gunzip serialized_object.gz
Now the file serialized_object contains the attributes in JSON format which you can edit. After editing you can store its contents back in chef server by following this:
Run: gzip serialized_object
Run: xxd -p serialized_object.gz > serialized_object.hex
Now you need to use the PostgreSQL client and insert the Hex data (be sure to remove prefix backslashes and x from the hex string) with the following query:
update nodes set serialized_object = decode('1f8b08000...','hex') where name = ''
Hope this helps someone :)

How do I do backups in MySQL? [duplicate]

This question already has answers here:
How do I backup a MySQL database?
(5 answers)
Closed 9 years ago.
How do I do backups in MySQL?
I'm hoping there'll be something better than just running mysqldump every "x" hours.
Is there anything like SQL Server has, where you can take a full backup each day, and then incrementals every hour, so if your DB dies you can restore up to the latest backup?
Something like the DB log, where as long as the log doesn't die, you can restore up to the exact point where the DB died?
Also, how do these things affect locking?
I'd expect the online transactions to be locked for a while if I do a mysqldump.
You might want to look at incremental backups.
mysqldump is a reasonable approach, but bear in mind that for some engines, this will lock your tables for the duration of the dump - and this has availability concerns for large production datasets.
An obvious alternative to this is mk-parallel-dump from Maatkit (http://www.maatkit.org/) which you should really check out if you're a mysql administrator. This dumps multiple tables or databases in parallel using mysqldump, thereby decreasing the amount of total time your dump takes.
If you're running in a replicated setup (and if you're using MySQL for important data in production, you have no excuses not to be doing so), taking dumps from a replication slave dedicated to the purpose will prevent any lock issues from causing trouble.
The next obvious alternative - on Linux, at least - is to use LVM snapshots. You can lock your tables, snapshot the filesystem, and unlock the tables again; then start an additional MySQL using a mount of that snapshot, dumping from there. This approach is described here: http://www.mysqlperformanceblog.com/2006/08/21/using-lvm-for-mysql-backup-and-replication-setup/
now i am beginning to sound like a marketeer for this product. i answered a question with it here, then i answered another with it again here.
in a nutshell, try sqlyog (enterprise in your case) from webyog for all your mysql requirements. it not only schedules backups, but also schedules synchronization so you can actually replicate your database to a remote server.
it has a free community edition as well as an enterprise edition. i recommend the later to you though i also reccomend you start with the comm edition and first see how you like it.
I use mysqlhotcopy, a fast on-line hot-backup utility for local MySQL databases and tables. I'm pretty happy with it.
the Percona guys made a open source altenative to innobackup ...
Xtrabackup
https://launchpad.net/percona-xtrabackup/
Read this article about XtraDB
http://www.linux-mag.com/cache/7356/1.html
You might want to supplement your current offline backup scheme with MySQL replication.
Then if you have a hardware failure you can just swap machines. If you catch the failure quickly you're users won't even notice any downtime or data loss.
I use a simple script that dumps the mysql database into a tar.gz file, encrypts it using gpg and sends it to a mail account (Google Mail, but that's irrelevant really)
The script is a Python script, which basically runs the following command, and emails the output file.
mysqldump -u theuser -p mypassword thedatabase | gzip -9 - | gpg -e -r 12345 -r 23456 > 2008_01_02.tar.gz.gpg
This is the entire backup. It also has the web-backup part, which just tar/gzips/encrypts the files. It's a fairly small site, so the web backups are much less than 20MB, so can be sent to the GMail account without problem (the MySQL dumps are tiny, about 300KB compressed). It's extremely basic, and won't scale very well. I run it once a week using cron.
I'm not quite sure how we're supposed to put longish scripts in answers, so I'll just shove it as a code-block..
#!/usr/bin/env python
#encoding:utf-8
#
# Creates a GPG encrypted web and database backups, and emails it
import os, sys, time, commands
################################################
### Config
DATE = time.strftime("%Y-%m-%d_%H-%M")
# MySQL login
SQL_USER = "mysqluser"
SQL_PASS = "mysqlpassword"
SQL_DB = "databasename"
# Email addresses
BACKUP_EMAIL=["email1#example.com", "email2#example.com"] # Array of email(s)
FROM_EMAIL = "root#myserver.com" # Only one email
# Temp backup locations
DB_BACKUP="/home/backupuser/db_backup/mysite_db-%(date)s.sql.gz.gpg" % {'date':DATE}
WEB_BACKUP="/home/backupuser/web_backup/mysite_web-%(date)s.tar.gz.gpg" % {'date':DATE}
# Email subjects
DB_EMAIL_SUBJECT="%(date)s/db/mysite" % {'date':DATE}
WEB_EMAIL_SUBJECT="%(date)s/web/mysite" % {'date':DATE}
GPG_RECP = ["MrAdmin","MrOtherAdmin"]
### end Config
################################################
################################################
### Process config
GPG_RECP = " ".join(["-r %s" % (x) for x in GPG_RECP]) # Format GPG_RECP as arg
sql_backup_command = "mysqldump -u %(SQL_USER)s -p%(SQL_PASS)s %(SQL_DB)s | gzip -9 - | gpg -e %(GPG_RECP)s > %(DB_BACKUP)s" % {
'GPG_RECP':GPG_RECP,
'DB_BACKUP':DB_BACKUP,
'SQL_USER':SQL_USER,
'SQL_PASS':SQL_PASS,
'SQL_DB':SQL_DB
}
web_backup_command = "cd /var/www/; tar -c mysite.org/ | gzip -9 | gpg -e %(GPG_RECP)s > %(WEB_BACKUP)s" % {
'GPG_RECP':GPG_RECP,
'WEB_BACKUP':WEB_BACKUP,
}
# end Process config
################################################
################################################
### Main application
def main():
"""Main backup function"""
print "Backing commencing at %s" % (DATE)
# Run commands
print "Creating db backup..."
sql_status,sql_cmd_out = commands.getstatusoutput(sql_backup_command)
if sql_status == 0:
db_file_size = round(float( os.stat(DB_BACKUP)[6] ) /1024/1024, 2) # Get file-size in MB
print "..successful (%.2fMB)" % (db_file_size)
try:
send_mail(
send_from = FROM_EMAIL,
send_to = BACKUP_EMAIL,
subject = DB_EMAIL_SUBJECT,
text = "Database backup",
files = [DB_BACKUP],
server = "localhost"
)
print "Sending db backup successful"
except Exception,errormsg:
print "Sending db backup FAILED. Error was:",errormsg
#end try
# Remove backup file
print "Removing db backup..."
try:
os.remove(DB_BACKUP)
print "...successful"
except Exception, errormsg:
print "...FAILED. Error was: %s" % (errormsg)
#end try
else:
print "Creating db backup FAILED. Output was:", sql_cmd_out
#end if sql_status
print "Creating web backup..."
web_status,web_cmd_out = commands.getstatusoutput(web_backup_command)
if web_status == 0:
web_file_size = round(float( os.stat(WEB_BACKUP)[6] ) /1024/1024, 2) # File size in MB
print "..successful (%.2fMB)" % (web_file_size)
try:
send_mail(
send_from = FROM_EMAIL,
send_to = BACKUP_EMAIL,
subject = WEB_EMAIL_SUBJECT,
text = "Website backup",
files = [WEB_BACKUP],
server = "localhost"
)
print "Sending web backup successful"
except Exception,errormsg:
print "Sending web backup FAIELD. Error was: %s" % (errormsg)
#end try
# Remove backup file
print "Removing web backup..."
try:
os.remove(WEB_BACKUP)
print "...successful"
except Exception, errormsg:
print "...FAILED. Error was: %s" % (errormsg)
#end try
else:
print "Creating web backup FAILED. Output was:", web_cmd_out
#end if web_status
#end main
################################################
################################################
# Send email function
# needed email libs..
import smtplib
from email.MIMEMultipart import MIMEMultipart
from email.MIMEBase import MIMEBase
from email.MIMEText import MIMEText
from email.Utils import COMMASPACE, formatdate
from email import Encoders
def send_mail(send_from, send_to, subject, text, files=[], server="localhost"):
assert type(send_to)==list
assert type(files)==list
msg = MIMEMultipart()
msg['From'] = send_from
msg['To'] = COMMASPACE.join(send_to)
msg['Date'] = formatdate(localtime=True)
msg['Subject'] = subject
msg.attach( MIMEText(text) )
for f in files:
part = MIMEBase('application', "octet-stream")
try:
part.set_payload( open(f,"rb").read() )
except Exception, errormsg:
raise IOError("File not found: %s"%(errormsg))
Encoders.encode_base64(part)
part.add_header('Content-Disposition', 'attachment; filename="%s"' % os.path.basename(f))
msg.attach(part)
#end for f
smtp = smtplib.SMTP(server)
smtp.sendmail(send_from, send_to, msg.as_string())
smtp.close()
#end send_mail
################################################
if __name__ == '__main__':
main()
You can make full dumps of InnoDB databases/tables without locking (downtime) via mysqldump with "--single-transaction --skip-lock-tables" options. Works well for making weekly snapshots + daily/hourly binary log increments (#Using the Binary Log to Enable Incremental Backups).
#Jake,
Thanks for the info.
Now, it looks like only the commercial version has backup features.
Isn't there ANYTHING built into MySQL to do decent backups?
The official MySQL page even recommends things like "well, you can copy the files, AS LONG AS THEY'RE NOT BEING UPDATED"...
The problem with a straight backup of the mysql database folder is that the backup will not necessarily be consistent, unless you do a write-lock during the backup.
I run a script that iterates through all of the databases, doing a mysqldump and gzip on each to a backup folder, and then backup that folder to tape.
This, however, means that there is no such thing as incremental backups, since the nightly dump is a complete dump. But I would argue that this could be a good thing, since a restore from a full backup will be a significantly quicker process than restoring from incrementals - and if you are backing up to tape, it will likely mean gathering a number of tapes before you can do a full restore.
In any case, whichever backup plan you go with, make sure to do a trial restore to ensure that it works, and get an idea of how long it might take, and exactly what the steps are that you need to go through.
the correct way to run incremental or continuous backups of a mysql server is with binary logs.
to start with, lock all of the tables or bring the server down. use mysql dump to make a backup, or just copy the data directory. you only have to do this once, or any time you want a FULL backup.
before you bring the server back up, make sure binary logging is enabled.
to take an incremental backup, log in to the server and issue a FLUSH LOGS command. then backup the most recently closed binary log file.
if you have all innodb tables, it's simpler to just use inno hot backup (not free) or mysqldump with the --single-transaction option (you'd better have a lot of memory to handle the transactions).
Binary logs are probably the correct way to do incremental backups, but if you don't trust binary file formats for permanent storage here is an ASCII way to do incremental backups.
mysqldump is not a bad format, the main problem is that it outputs stuff a table as one big line. The following trivial sed will split its output along record borders:
mysqldump --opt -p | sed -e "s/,(/,\n(/g" > database.dump
The resulting file is pretty diff-friendly, and I've been keeping them in a standard SVN repository fairly successfully. That also allows you to keep a history of backups, if you find that the last version got borked and you need last week's version.
This is a pretty solid solution for Linux shell. I have been using it for years:
http://sourceforge.net/projects/automysqlbackup/
Does rolling backups: daily, monthly, yearly
Lots of options
#Daniel,
in case you are still interested, there is a newish (new to me) solution shared by Paul Galbraith, a tool that allows for online backup of innodb tables called ibbackup from oracle which to quote Paul,
when used in conjunction with
innobackup, has worked great in
creating a nightly backup, with no
downtime during the backup
more detail can be found on Paul's blog
Sound like you are talking about transaction roll back.
So in terms of what you need, if you have the logs containing all historical queries, isn't that the backup already? Why do you need an incremental backup which is basically a redundant copy of all the information in DB logs?
If so, why don't you just use mysqldump and do the backup every once a while?