当前位置: 首页 > 图文教程 > 数据库 > MYSQL > 分步启动数据库以重命名数据文件

MYSQL
提高MySQL 查询效率的三个技巧
mysql同步复制搭建方法指南详细步骤
详解MySQL中DROP,TRUNCATE 和DELETE的区别实现mysql从零开始
MySQL Replace INTO的使用
mysql 分页优化解析
同时运行多个MySQL服务器的方法
mysql主从服务器同步心得体会
删除mysql数据库中的重复数据记录
mysql忘记密码的解决方法
mysql替换表中的字符串的sql语句
Lost connection to MySQL server during query的解决
mysql出现Error performing load command的解决方法
mysql中的“money”类型说明
mysql常见错误集锦
MYSQL administrator 使用
MYSQL初学者命令行使用指南
MySQL的Query Cache原理分析
linux下改良版本mysqldump来备份MYSQL数据库
mysql删除表中某一字段重复的记录
log引起的mysql不能启动的解决方法

MYSQL 中的 分步启动数据库以重命名数据文件


出处:互联网   整理: 软晨网(RuanChen.com)   发布: 2009-10-17   浏览: 182 ::
收藏到网摘: n/a

由于数据文件平时在数据库运行的时候处于使用状态,故当数据库处于打开状态时,管理员是无法重命名数据文件名字的。那么一定要更改这个数据文件的名字时,他该如何处理这个“顽疾”呢?

一、 数据库启动分三步走。

启动一个Oracle数据库时,都需要经过三个步骤。每完成一个步骤,数据库就进入一个特定的模式,以便保证数据库处于某种一致性的操作状态。管理员可以通过在启动命令中加入参数的方式,来控制数据库的启动步骤。有时候出于管理方面的需要,数据库的启动过程经常需要分布来完成。如数据库管理员进行日常的维护工作,很多都只需要启动第一步或者第二步即可。

第一步:启动例程。

每一个启动的数据库至少要对应一个例程。例程是Oracle用来管理数据库的一个实体。它是由一组逻辑内存结构和一系列后台服务进程所组成。当启动数据库时,这些内存结构以及服务进程得到分配、初始化和启动,以便用户能够与数据库进行通信。

但是,此时启动的数据库例程还没有跟任何数据库进行关联。换句话说,即使数据库不存在也可以启动例程。启动例程主要是跟初始化参数有关,主要是用来初始化数据库的运行环境。如果数据库的初始化参数文件损坏的话,那么就无法正常启动数据库例程了。也就是说,数据库例程主要牵涉到的是内存中的东西,如分配逻辑内存结构,在内存中驻扎一些必要的程序等等。如果数据库只完成了第一步即指启动例程的话,那么数据库管理员可以维护的工作是非常少的。如数据库管理员此时需要更改数据文件的名字,也是不行的。因为此时数据库历程还没有装载数据库,没有对应到具体的数据文件,故此时管理员还无法访问数据文件,对其进行维护。

若数据库管理员出于管理方面的需要,只要求启动第一个步骤的话,那么可以通过参数来进行控制。只要在启动数据库时,输入startup nomount命令即可。此时数据库只启动例程,而不装载数据库。Oracle数据库系统只会读取参数文件中的内容,只是为历程创建各种逻辑内存结构和后台服务进程。此时数据库管理员还不能够使用数据库中的任何文件。

第二步:装载数据库。

在启动例程时所用到的参数文件中,记载了数据库控制文件的存储位置与相关信息。当数据库在启动过程中企图装载数据库时,数据库系统会根据初始化参数文件中记载的控制文件信息去找到这个控制文件,并打开它。在这个控制文件中则记录着数据库的名称、数据文件的位置名称等关于数据库物理结构方面的信息。这里要注意,此时数据库系统会去读取这些信息,但是不并会去代开这些数据文件。只是为下一步打开数据库做好准备。

在装载数据库时,系统不会去读取数据文件和重做日志文件的内容。也就是说,此时数据库仍然是出于关闭状态的。用户无法与数据库建立连接,无法访问数据库并对数据库进行更改。显然,如果只是装载数据库而没有打开数据库的话,对于普通用户来说是没有多大作用的。但是对于数据库管理员来说此时他发展的舞台就很大了。因为只装载数据库而没有打开它,数据库管理员已经可以通过命令来维护数据库。例如,装载数据库但是还没有打开数据文件的状态下修改数据文件的名字。

如果管理员需要装载数据库而不打开数据库,则可以利用startup mount命令。这个命令主要来告诉数据库系统,启动历程并装载数据库,但是不打开数据库。此时数据库系统会打开控制文件并读取数据库名称、数据文件的位置和名称以及其他的一些相关信息。在这个模式下,数据库管理员已经可以对数据库进行一些维护。而且值得注意的是,有些工作只有在这种状态下才能够进行。通常情况下,若只是装载数据库而没有启动数据库的情况下,可以进行如下的日常维护工作。一是上面提到的对数据库的数据文件进行重命名;二是维护重做日志,如添加、删除日志文件或者更改重做日志文件的名字;三是执行数据库的完全恢复操作;四是改变数据库的归档模式等等。

第三步:打开数据库。

通常情况下,只装载数据库但是还没有打开数据库的情况下,应用程序时无法连接到数据库系统的。只有利用Open选项将数据库设置为打开状态后,应用程序才能够正常访问后台数据库系统。用户才能够查询、更改数据库中的记录。在打开数据库的过程中,例程将会根据控制文件中的信息找到对应的重做日志文件、数据文件等等。也就是说,第一步启动的例程会打开所有联机状态的数据文件和重做日志文件。这里要注意,只要控制文件中列出的任何一个重做日志文件或者数据文件损坏无法正常打开的话,则数据库也将无法正常 打开。此时数据库管理员需要进行数据库恢复才能够让数据库重新运转。

从这里也可以看出,如果数据库系统可以正常装载数据库并不一定表示数据文件与重做日志文件是正常的。因为在装载数据库的过程中,只读取了这些文件到存储位置与名字等等,并不会去判断这些文件是否可以使用。只有在试图打开数据库的时候,系统才会去判断这些文件的可用性。此时数据文件、日志文件等等以处于打开状态,故管理员是无法在此时对这些文件进行维护操作的,如位置移动、删除、重新能命名等等。

若要打开数据库,则可以采用Startup Open命令。这个命令告诉数据库系统启动例程、装载数据库并且把数据库设置为打开状态。将数据库设置为打开状态后,任何具有Create Session权限的用户都能够连接到数据库并对数据库进行日常的访问。

这里要注意一点,以上这个三个步骤并不是每次启动数据库都要如此一步步的走。如可以直接使用Startup命令,让Oracle系统直接把数据库启动到打开状态。管理员也可以利用Startup Mount命令直接启动到装载数据库的状态。具体要如何启动,主要是要看管理员维护数据库的目的。如需要把重做日志移动到另外一个地方时,那么在启动数据库的时候就只能够启动到第二步,而不能够直接启动到第三步。

另外,数据库启动状态的不同,其对应的动态性能视图中的内容也有所差异。如数据库处于装载数据库的状态下,管理员可以访问那些与SGA区相关的数据字典视图,而且还可以访问那些与控制文件相关的数据字典视图。但是此时动态性能视图中是找不到数据文件或者重做日志文件相关的信息。

二、 分步启动数据库以重命名数据文件。

那么如果现在数据库处于打开状态,数据库管理员该如何来重命名数据文件呢?其实步骤比较简单。只需要简单三个步骤就可以完成。

一是利用Startup Nomount命令把数据库启动到数据库装载状态。由于现在数据库处于打开状态,数据文件正在使用中,为此管理员不能够更改数据文件的名字。所以此时数据库管理员需要先把数据库关闭然后启动到数据库装载状态。此时数据文件没有被使用,故可以对其进行重命名。除了重命名之外,还可以移动数据文件的位置。

二是修改数据文件的名字。注意数据文件名字更改之后,同时要更改控制文件中的内容。否则的话,在打开数据库的时候,就会因为找不到控制文件中所列出的数据文件而导致启动的错误。同理,如果要移动数据文件的位置也是做类似的操作。

三是重新打开数据库。然后数据库管理员重新使用Startup Open命令来打开数据库。此时就完成了数据文件的重命名工作了.

CREATE TABLE table1(a INT NOT NULL UNIQUE,b INT NOT NULL UNIQUE,c INT NOT NULL UNIQUE);

假设table1中已经有了3条记录

a b c

1 1 1

2 2 2

3 3 3

下面我们使用REPLACE语句向table1中插入一条记录。

REPLACE INTO table1(a, b, c) VALUES(1,2,3);

返回的结果如下

Query OK, 4 rows affected (0.00 sec)

在table1中的记录如下

a b c

1 2 3

我们可以看到,REPLACE将原先的3条记录都删除了,然后将(1, 2, 3)插入。

二、UPDATE

UPDATE的功能是更新表中的数据。这的语法和INSERT的第二种用法相似。必须提供表名以及SET表达式,在后面可以加WHERE以限制更新的记录范围。

UPDATE table_anem SET column_name1 = value1, column_name2 = value2, WHERE ;

如下面的语句将users表中id等于123的记录的age改为24

UPDATE users SET age = 24 WHERE id = 123;

同样,可以使用UPDATE更新多个字段的值 UPDATE users SET age = 24, name = 'Mike' WHERE id = 123;

上面的UPDATE语句通过WHERE指定一个条件,否则,UPDATE将更新表中的所有记录的值。

在使用UPDATE更新记录时,如果被更新的字段的类型和所赋的值不匹配时,MySQL将这个值转换为相应类型的值。如果这个字段是数值类型,而且所赋值超过了这个数据类型的最大范围,那么MySQL就将这个值转换为这个范围最大或最小值。如果字符串太长,MySQL就将多余的字符串截去。如果设置非空字段为空,那么将这个字段设置为它们的默认值,数字的默认值是0,字符串的默认值是空串(不是null,是"")。

有两种情况UPDATE不会对影响表中的数据。

1. 当WHERE中的条件在表中没有记录和它匹配时。

2. 当我们将同样的值赋给某个字段时,如将字段abc赋为'123',而abc的原值就是'123'。

和INSERT、REPLACE一样,UPDATE也返回所更新的记录数。但这些记录数并不包括满足WHERE条件的,但却未被更新的记录。如下同的UPDATE语句就未更新任何记录。

UPDATE users SET age = 30 WHERE id = 12;

Query OK, 0 rows affected (0.00 sec)

需要注意的时,如果一个字段的类型是TIMESTAMP,那么这个字段在其它字段更新时自动更新。

在有些时候我们需要得到UPDATE所选择的行数,而不是被更新的行数。我们可以通过一些API来达到这个目的。如MySQL提供的C API提供了一个选项可以得到你想要的记录数。而MySQL的JDBC驱动得到的默认记录数也是匹配的记录数。

UPDATE和REPLACE基本类似,但是它们之间有两点不同。

1. UPDATE在没有匹配记录时什么都不做,而REPLACE在有重复记录时更新,在没有重复记录时插入。

2. UPDATE可以选择性地更新记录的一部分字段。而REPLACE在发现有重复记录时就将这条记录彻底删除,再插入新的记录。也就是说,将所有的字段都更新了。

三、DELETE和TRUNCATE TABLE

在MySQL中有两种方法可以删除数据,一种是DELETE语句,另一种是TRUNCATE TABLE语句。DELETE语句可以通过WHERE对要删除的记录进行选择。而使用TRUNCATE TABLE将删除表中的所有记录。因此,DELETE语句更灵活。

如果要清空表中的所有记录,可以使用下面的两种方法:

DELETE FROM table1

TRUNCATE TABLE table1

其中第二条记录中的TABLE是可选的。

如果要删除表中的部分记录,只能使用DELETE语句。

DELETE FROM table1 WHERE ;

如果DELETE不加WHERE子句,那么它和TRUNCATE TABLE是一样的,但它们有一点不同,那就是DELETE可以返回被删除的记录数,而TRUNCATE TABLE返回的是0。

如果一个表中有自增字段,使用TRUNCATE TABLE和没有WHERE子句的DELETE删除所有记录后,这个自增字段将起始值恢复成1.如果你不想这样做的话,可以在DELETE语句中加上永真的WHERE,如WHERE 1或WHERE true。

DELETE FROM table1 WHERE 1;

上面的语句在执行时将扫描每一条记录。但它并不比较,因为这个WHERE条件永远为true。这样做虽然可以保持自增的最大值,但由于它是扫描了所有的记录,因此,它的执行成本要比没有WHERE子句的DELETE大得多。

DELETE和TRUNCATE TABLE的最大区别是DELETE可以通过WHERE语句选择要删除的记录。但执行得速度不快。而且还可以返回被删除的记录数。而TRUNCATE TABLE无法删除指定的记录,而且不能返回被删除的记录。但它执行得非常快。

与标准的SQL语句不同,DELETE支持ORDER BY和LIMIT子句,通过这两个子句,我们可以更好地控制要删除的记录。如当我们只想删除WHERE子句过滤出来的记录的一部分,可以使用LIMIB,如果要删除后几条记录,可以通过ORDER BY和LIMIT配合使用。假设我们要删除users表中name等于"Mike"的前6条记录。可以使用如下的DELETE语句:

DELETE FROM users WHERE name = 'Mike' LIMIT 6;

一般MySQL并不确定删除的这6条记录是哪6条,为了更保险,我们可以使用ORDER BY对记录进行排序。

DELETE FROM users WHERE name = 'Mike' ORDER BY id DESC LIMIT 6;