mysql for oracle dbas

59
MySQL for Oracle DBAs Mark Leith Support Engineer, MySQL AB [email protected] 1

Upload: mark-leith

Post on 11-May-2015

5.265 views

Category:

Technology


6 download

DESCRIPTION

Presentation for MySQL UC 2006 on MySQL for the Oracle DBA

TRANSCRIPT

Page 1: MySQL for Oracle DBAs

MySQL for Oracle DBAs

Mark LeithSupport Engineer, MySQL AB

[email protected]

1

Page 2: MySQL for Oracle DBAs

2

Introduction

9 years database experience, starting with Oracle5 years MySQL experienceExtensive experience with database toolsWorking within the MySQL Support Group, for the Americas region

Page 3: MySQL for Oracle DBAs

AgendaMySQL ArchitectureBackup and RecoveryManaging space and tablesManaging MemoryTracing Sessions / AuditingMonitoring Tools and TipsConnecting MySQL to OracleQuestions

3

Page 4: MySQL for Oracle DBAs

Architecture

Product ArchitectureInternal Memory StructuresFilesystem Layout

BinariesDatabase / Table DatafilesLog Files

Permissions / Ownership

4

Page 5: MySQL for Oracle DBAs

Product Architecture

5

Page 6: MySQL for Oracle DBAs

Internal Memory Structures

6

Page 7: MySQL for Oracle DBAs

Filesystem Layout - BinariesWindows default: C:\Program Files\MySQL\MySQL Server x.x\binTarball default: /usr/local/mysql/bin RPM default: /usr/lib/mysql, /usr/bin & /usr/sbin (depending on RPM) MySQL Server executables

mysqld, mysqld-debug, mysqld-max

MySQL Client Utilities mysql, mysqldump, mysqlcheck, mysqlbinlog ..

Upgrade and Security scripts mysql_upgrade, mysql_fix_privilege_tables, mysql_secure_installation ..

7

Page 8: MySQL for Oracle DBAs

Filesystem Layout - DatafilesWindows default: C:\Program Files\MySQL\MySQL Server x.x\dataTarball default: /usr/local/mysql/data RPM default: /var/lib/mysql

Databases use “datadir”Default “mysql” database (SYSTEM Tablespace)One directory per databaseTable frm, data and index files within respective database directories

InnoDB uses “innodb_data_home_dir” Single tablespace file (ibdata1) located in “datadir” by defaultSet multiple datafiles with “innodb_datafile_path”frm files still created within each database directory under datadirRespect datadir conventions when using “innodb_file_per_table”

8

Page 9: MySQL for Oracle DBAs

Filesystem Layout - Log filesWindows Default: C:\Program Files\MySQL\MySQL Server x.x\dataTarball default: /usr/local/mysql/data RPM default: /var/log & /var/lib/mysql

Error Log (Alert Log)Set path with “log_error”, defaults to [hostname].err in “datadir”Binary Logs (Archive Redo Logs)Set with “log_bin”Record of all INSERT/UPDATE/DELETE activity<=5.0 Statement Based>=5.1 Statement Based and Row BasedInnoDB Transaction logs (Online Redo Logs)ib_logfile[x] set with “innodb_log_files_in_group” (default 2)Provides “Durability” to ACID complianceControl “checkpoint” times by altering the size of “innodb_log_file_size”

9

Page 10: MySQL for Oracle DBAs

10

Permissions / OwnershipNo concept of “ownership”Permissions stored in the “mysql” database“schema” == “database” rather than “users objects”

mysql.userUsername, host, password hash, global privileges, grant optionmysql.dbDatabase level privilegesmysql.tables_privTable level privilegesmysql.columns_privColumn level privilegesmysql.procs_privProcedure / Function privileges

Page 11: MySQL for Oracle DBAs

Backup and Recovery

Cold BackupFilesystem Snapshot (cp / rsync)

Warm Backup mysqldump

Hot Backup mysqldump, mysqlhotcopy

Using SlavesRecovery tips

11

Page 12: MySQL for Oracle DBAs

12

Backup - Cold BackupFull cold backup

All database directories and contents (including “mysql”)my.cnf/ini fileIf using InnoDB

All InnoDB datafilesAll InnoDB Transaction Redo Log files

Incremental Cold BackupAll of the above as a starting pointBinary logging enabled (”log-bin”)Only requires the latest binary logs since the last snapshotBeware of recovery times - applying the binary logs is a lot slower than file copying

Page 13: MySQL for Oracle DBAs

Backup - Warm Backupmysqldump

Uses FLUSH TABLES WITH READ LOCKLocks all other sessions

13

/* Backup db1, db2 and db3 to the same file, mixed MyISAM / InnoDB / other engines */

mysqldump -u root --opt --databases db1, db2, db3 > /backup/file.sql

/* Backup all databases to seperate files per database schema */#!/bin/bash

DATABASES=`mysql -u root -N -e 'SHOW DATABASES'`

OPTIONS1='--extended-insert --no-autocommit --quick --set-charset'OPTIONS2='--disable-keys --skip-add-locks --skip-comments'DUMPOPTIONS="$OPTIONS1 $OPTIONS2"

for D in $DATABASES ; do echo dumping $D ; echo "use $D;" > $D-data.sql echo "set autocommit=0;" >> $D-data.sql mysqldump -u root $DUMPOPTIONS --databases $D \ >> $D-data.sql ; done

Page 14: MySQL for Oracle DBAs

Backup - Hot Backupmysqldump

InnoDB onlyUses transactions and multi-versioning

/* Backup InnoDB databases to seperate files per database schema */

#!/bin/bash

DATABASES=`mysql -u root -N -e 'SHOW DATABASES'`

OPTIONS1='--extended-insert --no-autocommit --quick --set-charset --disable-keys'OPTIONS2=' --skip-add-locks --skip-comments --single-transaction --master-data'DUMPOPTIONS="$OPTIONS1 $OPTIONS2"

for D in $DATABASES ; do echo dumping $D ; echo "use $D;" > $D-data.sql echo "set autocommit=0;" >> $D-data.sql mysqldump -u root $DUMPOPTIONS --databases $D \ >> $D-data.sql ; done

14

Page 15: MySQL for Oracle DBAs

Backup - Hot Backupmysqlhotcopy

MyISAM and ARCHIVE tables only

LOCK TABLES ..; FLUSH TABLES; [cp | scp]; UNLOCK TABLES;

Requires Perl DBI

/* Hot Backup MyISAM / ARCHIVE table files to seperate directories per database schema */

#!/bin/bash

DATABASES=`mysql -u root -N -e 'SHOW DATABASES'`

DUMPOPTIONS='-u root --method=cp --noindices --flushlog'

for D in $DATABASES ; do echo copying $D ; DIRNAME=$D-`date '+%d%m%y'` mkdir ~/backup/$DIRNAME mysqlhotcopy $DUMPOPTIONS $D ~/backup/$DIRNAME done

15

Page 16: MySQL for Oracle DBAs

Backup - Slave Hot BackupRequires no downtime on the master systemAllows full cold backups easily, giving faster recovery timesAdds a server that can also be used to spread load

16

Master Slave

server-id 1 server-id 2

mysqldumpmysqlhotcopy

cpscp

rsyncLVM

Application Users

Reporting Users(Dataguard)

Page 17: MySQL for Oracle DBAs

17

Recovery Tipsmysqlbinlog

Perform point in time recovery directly to MySQLmysqlbinlog bin.000001 bin.000002 bin.000003 --stop-datetime=’2006-03-26 12:00:00’ | \mysql -u root -p

Output statements for single databases directly to MySQLmysqlbinlog bin.000001 bin.000002 bin.000003 --stop-datetime=’2006-03-26 12:00:00’ \--database sakila | mysql -u root -p

Output statements to plain text SQL files

mysqlbinlog bin.000001 bin.000002 bin.000003 --stop-datetime=’2006-03-26 12:00:00’ \--database sakila > /tmp/sakila-binlog-dump.sql

Page 18: MySQL for Oracle DBAs

Recovery Tips

18

Always use binary logging if possible

On recovery, make an initial copy of all current database filesWork on original set, leaving copy as secondary backup

Take regular full backups, to minimize recovery time

InnoDB Log file size controls full checkpoint activityIf using mysqlhotcopy, with --noindices, to rebuild indexes:

mysqlcheck --all-databases --auto-repair --use-frm

Page 19: MySQL for Oracle DBAs

Managing Space and Tables

19

MyISAM Storage EngineGathering stats, managing space

InnoDB Storage EngineGathering stats, managing space

Partitioning Partition Management

Page 20: MySQL for Oracle DBAs

20

Managing MyISAM SpaceAll table files stored within specific database directoryRow data held within [tablename].MYDIndex data held within [tablename].MYITable structure held within [tablename].frm

Deleted row space retained for future INSERT/UPDATE

Supports FULLTEXT Indexes (Oracle Text)

Table level locking (SELECT = Shared, INSERT, UPDATE, DELETE = Write)

Data warehousing storage engine

medusa:/usr/local/mysql/data/sakila root# ls -l film_text*-rw-rw---- 1 mysql wheel 119616 Apr 4 20:51 film_text.MYD-rw-rw---- 1 mysql wheel 205824 Apr 4 20:51 film_text.MYI-rw-rw---- 1 mysql wheel 8642 Apr 4 20:51 film_text.frm

Page 21: MySQL for Oracle DBAs

Managing MyISAM SpaceSHOW TABLE STATUS

mysql> SHOW TABLE STATUS LIKE 'film_text'\G*************************** 1. row *************************** Name: film_text Engine: MyISAM Version: 10 Row_format: Dynamic Rows: 950 Avg_row_length: 119 Data_length: 119616Max_data_length: 281474976710655 Index_length: 205824 Data_free: 6136 Auto_increment: NULL Create_time: 2006-04-03 14:16:02 Update_time: 2006-04-04 20:51:02 Check_time: 2006-04-04 20:51:17 Collation: utf8_general_ci Checksum: NULL Create_options: Comment: 1 row in set (0.00 sec)

Variable Length rows (VARCHAR etc.)“Fixed” = CHAR etc. static sized

Data size in bytes (~117KB)

Max size for the internal row pointer

Index size in bytes (~201KB)

Space reserved but unused(~6KB)

21

Page 22: MySQL for Oracle DBAs

22

Managing MyISAM SpaceINFORMATION_SCHEMA TABLES (DBA_ / USER_ tables)SELECT s.schema_name,CONCAT(IFNULL(ROUND((SUM(t.data_length)+SUM(t.index_length)) /1024/1024,2),0.00),"Mb") total_size,CONCAT(IFNULL(ROUND(((SUM(t.data_length)+SUM(t.index_length))-SUM(t.data_free))/1024/1024,2),0.00),"Mb") data_used,CONCAT(IFNULL(ROUND(SUM(data_free)/1024/1024,2),0.00),"Mb") data_free,IFNULL(ROUND((((SUM(t.data_length)+SUM(t.index_length))-SUM(t.data_free)) /((SUM(t.data_length)+SUM(t.index_length)))*100),2),0) pct_used,COUNT(table_name) total_tablesFROM INFORMATION_SCHEMA.SCHEMATA sLEFT JOIN INFORMATION_SCHEMA.TABLES t ON s.schema_name = t.table_schemaWHERE s.schema_name = "sakila"GROUP BY s.schema_nameORDER BY pct_used DESC\G*************************** 1. row *************************** schema_name: sakila total_size: 6.62Mb data_used: 6.62Mb data_free: 0.01Mb pct_used: 99.91total_tables: 221 row in set (0.08 sec)

Page 23: MySQL for Oracle DBAs

23

Managing MyISAM SpaceINFORMATION_SCHEMA TABLES (DBA_ / USER_ tables)

SELECT table_name, ROUND(((t.data_length+t.index_length)-t.data_free)/(t.data_length+t.index_length)*100) pct_used FROM information_schema.tables tWHERE table_schema = 'sakila'HAVING pct_used < 99ORDER BY table_name\G*************************** 1. row ***************************table_name: film_text pct_used: 981 row in set (0.05 sec)

To reclaim space to the filesystem run “OPTIMIZE TABLE”Creates a copy of the table, drops the original, and renames the copyRequires a table lockIf frequent activity on the table run “ANALYZE TABLE”Requires a table lock

Page 24: MySQL for Oracle DBAs

Managing MyISAM Spacemyisamchk -dvv

medusa:/Users/markleith/mysql/mysql-5.1.7/data/sakila root# ../../bin/myisamchk -dvv film_text

MyISAM file: film_textRecord format: PackedCharacter set: latin1_swedish_ci (8)File-version: 1Creation time: 2006-04-18 15:57:45Status: changedData records: 1000 Deleted blocks: 0Datafile parts: 1000 Deleted data: 0Datafile pointer (bytes): 6 Keyfile pointer (bytes): 6Datafile length: 119616 Keyfile length: 205824Max datafile length: 281474976710654 Max keyfile length: 288230376151710719Recordlength: 782

table description:Key Start Len Index Type Rec/key Root Blocksize1 2 2 unique short 1 29696 10242 5 254 fulltext ? packed 0 49152 1024 1 4 float 0

Field Start Length Nullpos Nullbit Type1 1 1 2 2 2 no zeros 3 4 767 varchar 4 771 10 1 1 blob

Should not be used whilst table is being used LOCK TABLE .. WRITE; or shutdown

24

Page 25: MySQL for Oracle DBAs

25

Managing InnoDB SpaceRow level locking Supports all transaction isolation levelsTables, Indexes and rollback created in a single tablespaceMultiple datafiles, with last datafile allowed to autoextend

medusa:/usr/local/mysql/data root# ls -l ib*-rw-rw---- 1 mysql wheel 5242880 Apr 8 21:25 ib_logfile0-rw-rw---- 1 mysql wheel 5242880 Apr 8 21:25 ib_logfile1-rw-rw---- 1 mysql wheel 18874368 Apr 8 21:25 ibdata1-rw-rw---- 1 mysql wheel 10485760 Apr 8 21:25 ibdata2

} Redo Logs

} Data Files

Filesystem InnoDB OracleDisk PartitionFileInodeFilesystem BlockDisk Block

TablespaceSegment (Table/Index)InodeExtent (64 pages, 1Mb)Page (UNIV_PAGE_SIZE 16Kb)

Tablespace(s)Segment (Table/Index)

ExtentDB_BLOCK_SIZE

Clustered Indexes (Index Organized Tables)Pages and extents managed like a filesystem

Page 26: MySQL for Oracle DBAs

SHOW TABLE STATUSmysql> SHOW TABLE STATUS LIKE 'rental'\G*************************** 1. row *************************** Name: rental Engine: InnoDB Version: 10 Row_format: Compact Rows: 16305 Avg_row_length: 97 Data_length: 1589248Max_data_length: 0 Index_length: 1261568 Data_free: 0 Auto_increment: 16050 Create_time: 2006-04-03 14:16:02 Update_time: NULL Check_time: NULL Collation: utf8_general_ci Checksum: NULL Create_options: Comment: InnoDB free: 4096 kB; (`customer_id`) REFER `sakila/customer`(`customer_id`) ON 1 row in set (0.10 sec)

New 5.0 InnoDB compact row format

Data size in bytes (~1.5Mb)

No Maximum (64Tb for tablespace)

Index size in bytes (~1.2Mb)

Unused space not reported by table

Managing InnoDB Space

Freespace reported by tablespace(4Mb)

26

Page 27: MySQL for Oracle DBAs

27

Managing InnoDB SpaceInnoDB Table and Tablespace Monitors

Dumped to the error log, or console (stdout) if no log-error

Dump the InnoDB internal Data Dictionary informationSwitched on with special InnoDB tables

create table innodb_table_monitor (a int) engine = innodb;

create table innodb_tablespace_monitor (a int) engine = innodb;

InnoDB Table Monitor

InnoDB Tablespace Monitor

Page 28: MySQL for Oracle DBAs

28

Managing InnoDB SpaceInnoDB Tablespace Monitor

================================================060403 14:20:31 INNODB TABLESPACE MONITOR OUTPUT================================================FILE SPACE INFO: id 0size 1152, free limit 832, free extents 3not full frag extents 4: used pages 202, full frag extents 2first seg id not used 0 114SEGMENT id 0 86 space 0; page 209; res 28 used 28; full ext 0fragm pages 28; free extents 0; not full extents 0: pages 0SEGMENT id 0 87 space 0; page 209; res 1 used 1; full ext 0fragm pages 1; free extents 0; not full extents 0: pages 0SEGMENT id 0 88 space 0; page 209; res 16 used 16; full ext 0fragm pages 16; free extents 0; not full extents 0: pages 0SEGMENT id 0 89 space 0; page 209; res 1 used 1; full ext 0fragm pages 1; free extents 0; not full extents 0: pages 0SEGMENT id 0 90 space 0; page 209; res 16 used 16; full ext 0fragm pages 16; free extents 0; not full extents 0: pages 0SEGMENT id 0 91 space 0; page 209; res 1 used 1; full ext 0fragm pages 1; free extents 0; not full extents 0: pages 0SEGMENT id 0 92 space 0; page 209; res 13 used 13; full ext 0fragm pages 13; free extents 0; not full extents 0: pages 0......

Page 29: MySQL for Oracle DBAs

29

Managing InnoDB SpaceInnoDB Tablespace Monitor

......SEGMENT id 0 84 space 0; page 2; res 96 used 53; full ext 0fragm pages 32; free extents 0; not full extents 1: pages 21

SEGMENT id 0 84 space 0; page 2;The Internal data dictionary id for the tablespace segment“space 0” is the system tablespace (ibdata files)“page 2” is where the inode of the segment is

res 96 used 53;“res” is total number of reserved pages“used” is the number of pages with data allocated

full ext 0The number of extents that are completely used

fragm pages 32;The first 32 pages are fully allocated

free extents 0;The number of extents that have no pages at all used

not full extents 1: pages 21The number of extents that have pages used but are not full“pages” is how many pages are used within these extents

Page 30: MySQL for Oracle DBAs

30

Managing InnoDB SpaceInnoDB Table Monitor

TABLE: name sakila/rental, id 0 26, columns 11, indexes 5, appr.rows 16305 COLUMNS: rental_id: DATA_INT len 4 prec 0; rental_date: DATA_INT len 8 prec 0; inventory_id: DATA_INT len 3 prec 0; customer_id: DATA_INT len 2 prec 0; return_date: DATA_INT len 8 prec 0; staff_id: DATA_INT len 1 prec 0; last_update: DATA_INT len 4 prec 0; DB_ROW_ID: DATA_SYS prtype 8 len 6 prec 0; DB_TRX_ID: DATA_SYS prtype 8 len 6 prec 0; DB_ROLL_PTR: DATA_SYS prtype 8 len 7 prec 0; INDEX: name PRIMARY, id 0 44, fields 1/9, type 3 root page 207, appr.key vals 16305, leaf pages 53, size pages 97 FIELDS: rental_id DB_TRX_ID DB_ROLL_PTR rental_date inventory_id customer_id return_date staff_id last_update INDEX: name rental_date, id 0 45, fields 3/4, type 2 root page 208, appr.key vals 17655, leaf pages 28, size pages 29 FIELDS: rental_date inventory_id customer_id rental_id INDEX: name idx_fk_inventory_id, id 0 46, fields 1/2, type 0 root page 210, appr.key vals 4467, leaf pages 16, size pages 17 FIELDS: inventory_id rental_id INDEX: name idx_fk_customer_id, id 0 47, fields 1/2, type 0 root page 211, appr.key vals 589, leaf pages 16, size pages 17 FIELDS: customer_id rental_id INDEX: name idx_fk_staff_id, id 0 48, fields 1/2, type 0 root page 212, appr.key vals 1, leaf pages 13, size pages 14 FIELDS: staff_id rental_id FOREIGN KEY CONSTRAINT sakila/fk_rental_staff: sakila/rental ( staff_id ) REFERENCES sakila/staff ( staff_id ) FOREIGN KEY CONSTRAINT sakila/fk_rental_inventory: sakila/rental ( inventory_id ) REFERENCES sakila/inventory ( inventory_id ) FOREIGN KEY CONSTRAINT sakila/fk_rental_customer: sakila/rental ( customer_id ) REFERENCES sakila/customer ( customer_id ) FOREIGN KEY CONSTRAINT sakila/fk_payment_rental: sakila/payment ( rental_id ) REFERENCES sakila/rental ( rental_id )

Page 31: MySQL for Oracle DBAs

31

Managing InnoDB SpaceInnoDB Table Monitor

TABLE: name sakila/rental, id 0 26, columns 11, indexes 5, appr.rows 16305 COLUMNS: rental_id: DATA_INT len 4 prec 0; rental_date: DATA_INT len 8 prec 0; inventory_id: DATA_INT len 3 prec 0; customer_id: DATA_INT len 2 prec 0; return_date: DATA_INT len 8 prec 0; staff_id: DATA_INT len 1 prec 0; last_update: DATA_INT len 4 prec 0; DB_ROW_ID: DATA_SYS prtype 8 len 6 prec 0; DB_TRX_ID: DATA_SYS prtype 8 len 6 prec 0; DB_ROLL_PTR: DATA_SYS prtype 8 len 7 prec 0;

“len” is column length in bytes, “prec” is the columns precision (DECIMAL etc.)“DB_ROW_ID”, “DB_TRX_ID” and “DB_ROLL_PTR” internal columns for transactions / multi-versioning

INDEX: name PRIMARY, id 0 44, fields 1/9, type 3 root page 207, appr.key vals 16305, leaf pages 53, size pages 97 FIELDS: rental_id DB_TRX_ID DB_ROLL_PTR rental_date inventory_id customer_id return_date staff_id last_update

“fields 1/9” is fields specifically specified in the index (1) and total fields in the index (9) “type” is index type: 3 = PRIMARY, 2 = UNIQUE, 0 = KEY, 1 = AUTO GENERATED PK“leaf pages 53” is the number of pages with data allocated (”used” in tablespace monitor)“size pages 97” is the total number of allocated pages (”res” in tablespace monitor)

Rows: 16305Avg_row_length: 97Data_length: 1589248Max_data_length: 0Index_length: 1261568Data_free: 0

16,384 * 97 = 1,589,248 (1.5Mb)

16,384 * (29+17+17+14) = 1,261,568 (1.2mb)

16,384 * (97-53) = 720,896 (~700Kb)

Page 32: MySQL for Oracle DBAs

32

Managing InnoDB SpaceAllocates the first 32 pages individually

After 32 pages allocated, allocates 1Mb extents To reclaim space to the tablespace run “OPTIMIZE TABLE”Reorganization process similar to MyISAMRequires a table lock

“ANALYZE TABLE” rarely needed, as InnoDB updates stats Not Uniform extent allocation, fragmentation highly possibleTo reorganize the tablespace:

mysqldump all tablesStop MySQLmv the InnoDB tablespace datafiles and log files to a backup locationStart MySQLLoad the mysqldump

Page 33: MySQL for Oracle DBAs

33

Partitioning (5.1)No extra costsAll storage engines support partitioning“Local” indexes only

Indexes only created locally to each partition“Global” indexes scheduled for 5.2

Indexes created across the entire partitioned tablePartition pruning already available at the optimizer levelAllow far greater table maintenance flexibility, with partition level locks

Page 34: MySQL for Oracle DBAs

34

Partitioning (5.1)RANGE partitioning: (As in Oracle 8i RANGE partitions)

Assigns rows to partitions based on column values falling within a given range.

LIST partitioning: (As in Oracle 9i LIST partitions)Similar to partitioning by range, except that the partition is selected based on columns matching one of a set of discrete values.

HASH partitioning: (Not possible in Oracle)A partition is selected based on the value returned by a user-defined expression that operates on column values in rows to be inserted into the table. The function may consist of any expression valid in MySQL that yields a non-negative integer value.

KEY partitioning: (As in Oracle 8i HASH partitions)Similar to partitioning by hash, except that only one or more columns to be evaluated are supplied, and the MySQL server provides its own hashing function. These columns can contain other than integer values, since the hashing function supplied by MySQL guarantees an integer result regardless of the column data type.

Subpartitioning: (As in Oracle 9i composite partitions)Subpartition tables that are partitioned by RANGE or LIST. Subpartitions may use either HASH or KEY partitioning.

Page 35: MySQL for Oracle DBAs

35

Partitioning (5.1)Moving to Partitioned tables

CREATE TABLE `RENTAL` ( `rental_id` int(11) NOT NULL auto_increment, `rental_date` datetime NOT NULL, `inventory_id` mediumint(8) unsigned NOT NULL, `customer_id` smallint(5) unsigned NOT NULL, `return_date` datetime default NULL, `staff_id` tinyint(3) unsigned NOT NULL, `last_update` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, PRIMARY KEY (`rental_id`), UNIQUE KEY `rental_date` (`rental_date`,`inventory_id`,`customer_id`), KEY `idx_fk_inventory_id` (`inventory_id`), KEY `idx_fk_customer_id` (`customer_id`), KEY `idx_fk_staff_id` (`staff_id`), CONSTRAINT `fk_rental_staff` FOREIGN KEY (`staff_id`) REFERENCES `staff` (`staff_id`) ON UPDATE CASCADE, CONSTRAINT `fk_rental_inventory` FOREIGN KEY (`inventory_id`) REFERENCES `inventory` (`inventory_id`) ON UPDATE CASCADE, CONSTRAINT `fk_rental_customer` FOREIGN KEY (`customer_id`) REFERENCES `customer` (`customer_id`) ON UPDATE CASCADE) ENGINE=InnoDB DEFAULT CHARSET=utf8

PARTITION key must be a part of the PRIMARY KEY, if any, if not, any columnPARTITION key must be on an INT column, or expression returning an INTDo not support FOREIGN KEY constraints

Page 36: MySQL for Oracle DBAs

36

Partitioning (5.1)Moving to Partitioned tables

DROP TABLE rental_parts;CREATE TABLE `rental_parts` ( `rental_id` int(11) NOT NULL auto_increment, `rental_date` datetime NOT NULL, `inventory_id` mediumint(8) unsigned NOT NULL, `customer_id` smallint(5) unsigned NOT NULL, `return_date` datetime default NULL, `staff_id` tinyint(3) unsigned NOT NULL, `last_update` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP, PRIMARY KEY (`rental_id`, `rental_date`), UNIQUE KEY `rental_date` (`rental_date`,`inventory_id`,`customer_id`), KEY `idx_inventory_id` (`inventory_id`), KEY `idx_customer_id` (`customer_id`), KEY `idx_staff_id` (`staff_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8PARTITION BY RANGE (YEAR(`rental_date`))( PARTITION rental_2002 VALUES LESS THAN (2003), PARTITION rental_2003 VALUES LESS THAN (2004), PARTITION rental_2004 VALUES LESS THAN (2005), PARTITION rental_2005 VALUES LESS THAN (2006), PARTITION rental_2006 VALUES LESS THAN MAXVALUE);INSERT INTO rental_parts (SELECT * FROM rental);

DROP TABLE rental;RENAME TABLE rental_parts TO rental;

Page 37: MySQL for Oracle DBAs

37

Partitioning (5.1)INFORMATION_SCHEMA.PARTITIONS

************************** 1. row *************************** table_schema: sakila table_name: rentalpartition_name: rental_2002 table_rows: 0 data_length: 16384 index_length: 65536*************************** 2. row *************************** table_schema: sakila table_name: rentalpartition_name: rental_2003 table_rows: 0 data_length: 16384 index_length: 65536*************************** 3. row *************************** table_schema: sakila table_name: rentalpartition_name: rental_2004 table_rows: 0 data_length: 16384 index_length: 65536

*************************** 4. row *************************** table_schema: sakila table_name: rentalpartition_name: rental_2005 table_rows: 16272 data_length: 1589248 index_length: 1818624*************************** 5. row *************************** table_schema: sakila table_name: rentalpartition_name: rental_2006 table_rows: 182 data_length: 16384 index_length: 655365 rows in set (0.02 sec)

SELECT table_schema, table_name, partition_name, table_rows, data_length, index_lengthFROM information_schema.partitions WHERE table_name = 'rental’AND table_schema = ‘sakila’

Page 38: MySQL for Oracle DBAs

38

Partitioning (5.1)Partition Management - ALTER TABLE

REBUILD PARTITION (No Oracle equivalent)Used to rebuild/reorganize a partitionALTER TABLE rental REBUILD PARTITION rental_2005;

OPTIMIZE PARTITION (No Oracle equivalent)Used like OPTIMIZE TABLE for each storage engine, at the partition levelALTER TABLE rental OPTIMIZE PARTITION rental_2004;

ANALYZE PARTITION (analyze table emp partition(p1) compute statistics;)Reads and stores the key distributions for partitionsALTER TABLE rental ANALYZE PARTITION rental_2005;

CHECK PARTITION (No Oracle equivalent)Checks specific partitions for errors (like CHECK TABLE)ALTER TABLE rental CHECK PARTITION rental_2003;

REPAIR PARTITION (No Oracle equivalent)Used for MyISAM partitions, if they become corrupt (like REPAIR TABLE)ALTER TABLE rental REPAIR PARTITION rental_2003;

Page 39: MySQL for Oracle DBAs

39

Partitioning (5.1)ADD PARTITION (Same as Oracle)

Add a partition to the table (to the end of the ALTER TABLE rental ADD PARTITION (PARTITION rental_2007 VALUES LESS THAN (2008);

DROP PARTITION (Same as Oracle)Remove a partition from the tableALTER TABLE rental DROP PARTITION rental_2002;

REORGANIZE PARTITION (ALTER TABLE .. SPLIT / MERGE PARTITION)Split a partition in to multiple partitions, or merge several partitions in to one

ALTER TABLE rental REORGANIZE PARTITION rental_2002 INTO ( PARTITION rental_pre_2002 VALUES LESS THAN (2002), PARTITION rental_2002 VALUES LESS THAN (2003));

ALTER TABLE rental REORGANIZE PARTITION rental_pre_2002, rental_2002 INTO (PARTITION rental_pre_2003 VALUES LESS THAN (2003));

Partition Management - ALTER TABLE

Page 40: MySQL for Oracle DBAs

40

Managing Memory

SHOW [GLOBAL | SESSION] STATUSMyISAM Key CacheInnoDB Buffer PoolQuery Cache Thread Buffers

Page 41: MySQL for Oracle DBAs

41

Managing MemorySHOW [GLOBAL | SESSION] STATUS [LIKE ‘string’]

Provides session and global level server statisticsGives information about various aspects of the server such as locks, memory usage, disk usage, network activity etc.Akin to various of the V$ views in partsReset statistics with “FLUSH STATUS”

mysql> SHOW STATUS;+-------------------------------------+-----------------+| Variable_name | Value |+-------------------------------------+-----------------+| Aborted_clients | 0 || Aborted_connects | 0 || Bytes_received | 155372598 || Bytes_sent | 1176560426 || Connections | 30023 |...| Created_tmp_disk_tables | 0 || Created_tmp_tables | 8340 || Created_tmp_files | 60 |

Page 42: MySQL for Oracle DBAs

42

Managing MemoryMyISAM Key Cache

Caches only MyISAM index dataKey status indicators:

Key_reads - Index blocks read from diskKey_read_requests - Index blocks read from cacheKey_writes - Index blocks written on diskKey_write_requests - Index blocks written within cache

Monitor overall usage with a hit ratio indicatorSHOW GLOBAL STATUS LIKE ‘key_read%’;100-((key_reads/key_read_requests)*100)

Set with “key_buffer_size” in my.cnf, or interactively:SET GLOBAL key_buffer_size = 50*1024*1024;

Current maximum 4Gb

Page 43: MySQL for Oracle DBAs

43

Managing MemoryInnoDB Buffer Pool

Caches InnoDB table and index dataKey status indicators (5.0 or greater):

Innodb_buffer_pool_reads - Pages read from diskInnodb_buffer_pool_read_requests - Pages read from the cacheInnodb_buffer_pool_wait_free - Number of waits to create or flush pageInnodb_buffer_pool_read_ahead_seq - Incremented for full table scans

Monitor overall usage with a hit ratio indicatorSHOW GLOBAL STATUS LIKE ‘innodb_buffer_pool_read%’;100-((Innodb_buffer_pool_reads/Innodb_buffer_pool_read_requests)*100)

Set with “innodb_buffer_pool_size” in my.cnfNot a dynamic variable (requires a restart)Typically 50-80% of dedicated server’s available RAM

Page 44: MySQL for Oracle DBAs

44

Managing MemoryQuery Cache

Caches query result sets as pre-formed network packetsKey status indicators:

Qcache_hits - Queries satisfied from the cacheQCache_inserts - Query result sets added to the cacheQcache_lowmem_prunes - Query results flushed due to lack of memoryQcache_free_memory - Bytes free

Monitor overall usage with a hit ratio indicator100-((Qcache_inserts/Qcache_hits)*100)

Set with “query_cache_size” and “query_cache_type”SET GLOBAL query_cache_size = 32*1024*1024;

Control block allocation size with “query_alloc_block_size”Control size of result sets cached with “query_cache_limit”

Page 45: MySQL for Oracle DBAs

45

Managing MemoryPer Thread Buffers

Possible to set dynamically at the session level with “SET SESSION variable = ..”

sort_buffer_sizeAllocated per thread for each sort operation (ORDER BY / GROUP BY)Values larger than 2-4Mb rarely benefit performanceMonitor for high “Sort_merge_passes” in SHOW GLOBAL STATUS

read_rnd_buffer_sizeUsed when reading sorted rows after an ORDER BY on an indexed columnLarger result sets get better performance from larger buffer sizeLeave GLOBAL default and use SET SESSION when needed for large queries

read_buffer_sizeAllocated per thread for each full MyISAM table scanValues larger than 2-4Mb rarely benefit performanceMonitor for high “Handler_read_rnd_next” / “Select_scan”

join_buffer_sizeAllocated per thread for each JOIN causing a full table scanPossible many allocated per thread with complex/multiple joinsValues larger than 2-4Mb rarely benefit performance

Page 46: MySQL for Oracle DBAs

46

Managing Memory

tmp_table_sizeAllocated per thread for each complex GROUP BY or subquries etc.Monitor with “Created_tmp_tables” and “Created_tmp_disk_tables”32-64Mb depending on memory available

binlog_cache_sizeAlso allocated per thread Caches Binary Log entries for multiple statement transactionsMonitor with “Binlog_cache_use” and “Binlog_disk_cache_use” satus variablesLimit with “max_binlog_cache_size” system variable

thread_cache_sizeGLOBAL level variableCaches threads/sessions with an already allocated stack for faster connectionsWhen sessions disconnect they have their buffers flushed and are re-addedMonitor with ratio of “Threads_created” to “Connections”

Per Thread Buffers

Page 47: MySQL for Oracle DBAs

47

Tracing Sessions / AuditingSHOW FULL PROCESSLIST (V$SESSION)

mysql> SHOW FULL PROCESSLIST;+----+------+-----------------------+---------+------------------+--------------+-------------+----------------------------------------+| Id | User | Host | db | Command | Time | State | Info | +----+------+-----------------------+---------+------------------+---------------+-------------+---------------------------------------+| 1 | root | localhost:32820 | merlin | Sleep | 1 | | NULL || 3 | root | localhost:32822 | merlin | Sleep | 507 | | NULL || 4 | root | localhost:32823 | merlin | Sleep | 507 | | NULL || 5 | root | localhost:32824 | merlin | Sleep | 506 | | NULL || 6 | root | localhost:32826 | merlin | Sleep | 21207 | | NULL || 7 | root | localhost:32827 | merlin | Query | 0 | Sending data | SELECT data_id,value |FROM `dc_INTEGER` WHERE `begin_time` =(SELECT MAX(`begin_time`) FROM `dc_INTEGER` | WHERE `collect_id`=90) AND `collect_id`=90 FOR UPDATE || 16 | root | localhost:33447 | NULL | Sleep | 3 | | NULL || 19 | root | localhost:48885 | merlin | Sleep | 7 | | NULL || 27 | root | localhost | NULL | Query | 0 | NULL | SHOW FULL PROCESSLIST |+----+------+-----------------------+---------+------------------+--------------+-------------+----------------------------------------+9 rows in set (0.00 sec)

PROCESS privilege required to view the full session listUse FULL keyword to include currently executing SQL

Page 48: MySQL for Oracle DBAs

39

Tracing Sessions / AuditingPROCESSLIST states

Sleeping - The thread is idle

Opening Tables - Trying to open a new tableCopying to tmp table - Creating in memory temporary table

Copying to tmp table on disk - Creating disk based temporary tableSorting for group - Performing a GROUP BY operation

Sorting for order - Performing an ORDER BY operationSending Data - Processing and returning SELECT results

Updating - Currently updating row valuesWriting to net - Server is writing packets to the client

Locked - The session is currently blocked by another sessions lock(s)Killed - Kill flag set, waiting for next opportunity to release thread

Page 49: MySQL for Oracle DBAs

49

Tracing Sessions / AuditingGeneral Query Log

Records all connections and statements, successful or failedSet with the “log” server variable

log=/var/log/mysql-query.logDoes incur a slight performance overhead

[markleith@medusa:~] $ sudo tail -n 15 mysql/mysql-5.1.7/data/general.logPassword:./mysql-5.1.7/bin/mysqld-debug, Version: 5.1.7-beta-debug-log. started with:Tcp port: 5017 Unix socket: /Users/markleith/mysql/mysql-5.1.7.sockTime Id Command Argument060419 11:58:49 1 Connect root@localhost on 060419 11:58:57 1 Query SELECT DATABASE() 1 Init DB sakila060419 11:59:00 1 Query show tables060419 11:59:19 1 Query desc staff060419 12:00:04 1 Query select staff_id, first_name, last_name, email, username, passwordfrom staff

Page 50: MySQL for Oracle DBAs

51

Tracing Sessions / AuditingNew in 5.1 (True V$SESSION, V$SQLTEXT, sys.aud$)

INFORMATION_SCHEMA.PROCESSLISTmysql.general_log - Set with “--log-output=TABLE,FILE” (or either)mysql.slow_log - Set with “--log-output=TABLE,FILE” (or either)

mysql> SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST;+----+---------+--------------+---------+----------------+---------+--------------+------------------------------------------------------------------------------------+ | ID | USER | HOST | DB | COMMAND | TIME | STATE | INFO |+----+---------+--------------+---------+----------------+---------+--------------+------------------------------------------------------------------------------------+ | 2 | root | localhost | | Query | 0 | preparing | SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST | | 1 | root | localhost | sakila | Sleep | 2434 | | |+----+---------+--------------+---------+----------------+---------+--------------+------------------------------------------------------------------------------------+2 rows in set (0.00 sec)

mysql> SELECT p.id, g.event_time, p.user, p.host, g.command_type, replace(g.argument,'\n', '') statement -> FROM information_schema.processlist p -> JOIN mysql.general_log g ON p.id = g.thread_id -> WHERE p.id = 1 AND g.event_time > NOW() - INTERVAL 3 HOUR ORDER BY event_time;+----+----------------------------+------+--------------+----------------+------------------------------------------------------------------------------------------------------------+| id | event_time | user | host | command_type | statement |+----+----------------------------+------+--------------+----------------+------------------------------------------------------------------------------------------------------------+| 1 | 2006-04-19 11:58:49 | root | localhost | Connect | root@localhost on || 1 | 2006-04-19 11:58:57 | root | localhost | Query | SELECT DATABASE() || 1 | 2006-04-19 11:58:57 | root | localhost | Init DB | sakila || 1 | 2006-04-19 11:59:00 | root | localhost | Query | show tables || 1 | 2006-04-19 11:59:19 | root | localhost | Query | desc staff || 1 | 2006-04-19 12:00:04 | root | localhost | Query | select staff_id, first_name, last_name, email, username, passwordfrom staff |+----+----------------------------+------+--------------+----------------+------------------------------------------------------------------------------------------------------------+

Page 51: MySQL for Oracle DBAs

52

Tracing Sessions / AuditingTriggers

DML triggers availble [BEFORE | AFTER] [INSERT | UPDATE | DELETE]

System triggers such as “LOGON” not yet availableOnly one trigger of each type allowed (i.e. BEFORE UPDATE)Can perform multiple actions between BEGIN ... END blocks

CREATE TABLE audit_payment ( audit_id INT AUTO_INCREMENT PRIMARY KEY, payment_id INT, new_staff_id TINYINT, old_staff_id TINYINT, new_amount DECIMAL(5,2), old_amount DECIMAL(5,2), updated_by VARCHAR(64), update_time DATETIME);

CREATE TRIGGER tr_audit_payment AFTER UPDATE ON paymentFOR EACH ROWINSERT INTO audit_payment VALUES (NULL,OLD.payment_id,NEW.staff_id,OLD.staff_id,NEW.amount,OLD.amount,CURRENT_USER(),NOW());

Page 52: MySQL for Oracle DBAs

53

Tracing Sessions / AuditingTriggersmysql> select * from payment where payment_id = 16049;+-----------------+-------------------+-----------+-------------+------------+----------------------------+-----------------------------+| payment_id | customer_id | staff_id | rental_id | amount | payment_date | last_update |+-----------------+-------------------+-----------+-------------+------------+----------------------------+-----------------------------+| 16049 | 599 | 2 | 15725 | 2.99 | 2005-08-23 11:25:00 | 2006-02-15 22:24:13 |+-----------------+-------------------+-----------+-------------+------------+----------------------------+-----------------------------+1 row in set (0.00 sec)

mysql> UPDATE payment SET amount = 1.99 WHERE payment_id = 16049;Query OK, 1 row affected (0.03 sec)Rows matched: 1 Changed: 1 Warnings: 0

mysql> select * from audit_payment\G*************************** 1. row *************************** audit_id: 1 payment_id: 16049new_staff_id: 2old_staff_id: 2 new_amount: 1.99 old_amount: 2.99 updated_by: root@localhost update_time: 2006-04-19 13:33:481 row in set (0.00 sec)

Page 53: MySQL for Oracle DBAs

Monitoring Tools

54

MySQL Network 2.0

Server Overview

Page 54: MySQL for Oracle DBAs

55

Monitoring ToolsAlert overview

Page 55: MySQL for Oracle DBAs

56

Monitoring ToolsAlert History

Graphing/Trending

Page 56: MySQL for Oracle DBAs

57

Connecting Oracle to MySQLHeterogeneous Services

Connects Oracle to MySQL via MyODBCCan create database links from OracleOracle -> MySQL only

Install and configure MyODBCCreate and edit $ORACLE_HOME/hs/admin and add:

/* Replace "MySQL" below with your DSN specified within your MyODBC setup */

HS_FDS_CONNECT_INFO = MySQL HS_FDS_TRACE_LEVEL = OFF

Edit $ORACLE_HOME/network/admin/listener.ora and add:(SID_DESC =(PROGRAM = hsodbc)(ORACLE_HOME = oracle/product/92) /* Your $ORACLE_HOME */(SID_NAME = MySQL) /* Your DSN */)

Page 57: MySQL for Oracle DBAs

58

Connecting Oracle to MySQLHeterogeneous Services

Add the following to the tnsnames.ora file:MYSQL =(DESCRIPTION=(ADDRESS=(PROTOCOL=tcp)(HOST=localhost)(PORT=1521))(CONNECT_DATA=(SID=MYSQL))(HS=OK))

Reload your Oracle listener (lsnrctl reload) and then log onto to the Oracle database. To set up the database link:

CREATE DATABASE LINK mysql CONNECT TO "my_user" IDENTIFIED BY "my_password" USING 'mysql';

Page 58: MySQL for Oracle DBAs

59

Connecting Oracle to MySQLHeterogeneous Services

SQL> COUNT(*) FROM film@mysql;

COUNT(*)----------1000

SQL> DESC film@mysql5;Name Null? Type----------------------------------------- -------- ----------------------------film_id NUMBER(10)category_id NOT NULL NUMBER(10)title NOT NULL VARCHAR2(27)description LONGrental_duration NOT NULL NUMBER(3)length NUMBER(10)rating CHAR(5)

SQL>INSERT INTO film@mysql5 VALUES (1000000,1,'test','test',1,1,'PG');

1 row created.---change prompts---mysql> USE sakila

mysql> SELECT max(film_id) FROM film;+------------------+| max(film_id) |+------------------+| 1000000 |+------------------+

Page 59: MySQL for Oracle DBAs

60

Questions?