Ubuntu下安装Mysql(5.5)和主从功能配置

本文详细介绍了在Ubuntu系统中安装Mysql并配置主从复制的过程,包括解决常见问题的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Ubuntu下安装Mysql5.5)和主从功能配置

经过几天的折腾,终于把Mysql主从功能配置好了,其实配置很简单,不过还是遇到了各式各样的错误,下面总结一下,

在安装之前,可以先ping一下两台服务器是否可以互相通信,

ubuntu下在线安装Mysql相对比较简单,输入如下命令便可自动安装完成。

sudo apt-get install mysql-server

安装的过程中如果无法正常获取源数据,可以使用以下命令安装更新ubuntu的数据源

sudo apt-get update

我们可以通过netstat -tap|grep mysql来查看系统是否已经有了mysql服务

查询mysql 是否在运行,如输入一下命令

service mysql status

mysql start/running, process 10786

Mysql远程登录测试 

在主机上添加一个账户slave

进入mysql

输入以下的命令

grant replication slave,reload,super on *.* to slave@xx.103.118.99 identified by 'slave' ;

其中"slave@xx.103.118.99"slave是用户名,密码是'slave';

查看授权是否成功,可以输入以下命令:

select user ,host,password from mysql.user

在从机上进行测试,输入:

mysql -u slave -h xx.103.118.92 –p

若成功,显示如下:

Enter password:

Welcome to the MySQL monitor.  Commands end with ; or \g.

Your MySQL connection id is 38

Server version:5.5.28-0ubuntu0.12.04.3-log (Ubuntu)

 

Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its

affiliates. Other names may be trademarks of their respective

owners.

 

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

 

若出现如下错误,

ERROR 2003 (HY000): Can't connect to MySQL server on "host" (111)

需要修改主机的配置文件将地址绑定给注释掉(/etc/mysql/my.cnf):

#bind-address           = 127.0.0.1  <---注释掉这一行就可以远程登录了

 

Mysql的主从复制原理很简单,就是从服务器读取主服务器的binlog,然后根据binlog的数据库操作记录来更新数据库。根据这一原理,可以对my.cnf配置文件进行相应的修改

主要添加如下配置:

server-id=1

log_bin=/var/log/mysql/mysql-bin.log

binlog_do_db=test   要进行主从复制的数据库

binlog_ignore_db=information_schema 不需要进行主从复制的数据库

 

配置好后重启mysql

sudo /etc/init.d/mysql restart

 

进入mysql,输入:

 

mysql> flush privileges;

mysql> show master status;

+------------------+----------+--------------+--------------------+

| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB   |

+------------------+----------+--------------+--------------------+

| mysql-bin.000011 |      107 | test         | information_schema |

+------------------+----------+--------------+--------------------+

1 row in set (0.00 sec)

 

从机配置:(/etc/mysql/my.cnf):

server-id=2(不可以和主机id一样)

log_bin=/var/log/mysql/mysql-bin.log

replicate-do-db=test       要进行主从复制的数据库

replicate-ignore-db=information_shcema     不需要进行主从复制的数据库

 

配置好后重启mysql

sudo /etc/init.d/mysql restart

 

进入mysql,输入

stop slave;

change master to

master_host='xx.103.118.92',master_user='slave',master_password='slave',master_log_file='log.000011',master_log_pos=107;

 

start slave;

show slave status\G;

如果出现: 

Slave_IO_Running: Yes

Slave_SQL_Running: Yes 

以上两项都为Yes,那说明没问题了。

可以在主机上进行数据操作,看看从机是否会自动同步

若在从机遇到下面的错误,主要是主从同步的问题,Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'Could not find first log file name in

binary log index file'

可以执行一下命令

stop slave;

reset slave;

start slave

 

安装成功后,我又重新安装配置了几次,发现如果没有执行reset slave,问题就无法解决。

<think>这个错误信息是MySQL返回的语法错误提示,指出在SQL语句的第11行附近存在语法错误。具体错误位置在窗口函数定义(WINDOW子句)的起始处。错误原因可能是MySQL版本不支持WINDOW子句,或者语法结构有误。 错误分析: 在之前提供的解决方案中,我们使用了以下结构: WINDOW w AS (...) 这个特性是MySQL 8.0引入的。如果您的MySQL版本低于8.0,则不支持这种命名窗口的语法。 解决方案: 有两种修改方式: 1. 升级MySQL到8.0或更高版本(推荐,因为窗口函数能极大提高复杂查询的效率)。 2. 修改SQL,不使用WINDOW子句,而是将窗口定义直接写入每个窗口函数中(适用于MySQL 8.0+但不使用命名窗口)或降级到兼容低版本的写法。 但是,考虑到错误提示中提到的位置,还有一种可能是窗口函数的定义位置不正确。在MySQL中,WINDOW子句必须位于FROMWHERE等子句之后,GROUP BY之前。但我们的查询中,WINDOW子句是放在FROMWHERE之后,但位于GROUP BY之前?实际上,在之前的查询中,我们并没有使用GROUP BY,而是使用了窗口函数子查询。 重新检查之前的查询结构: SELECT ... FROM ... WHERE ... WINDOW w AS (...) 这个顺序是合法的。但是,如果MySQL版本低于8.0,则根本不允许WINDOW关键字。 因此,我们假设错误是由于MySQL版本低于8.0造成的。 针对低版本MySQL5.7及以下)的改写方案: 由于原查询使用了窗口函数(ROW_NUMBERFIRST_VALUE),在低版本MySQL中无法使用,因此需要采用其他方法。 方法:使用子查询模拟窗口函数的功能,即通过子查询获取每个分组内的最新记录。 步骤: 1. 先为每个分组(t5.categoryName, t5.NAME, t5.model, t1.management_dept_id)找到最新入库时间(create_time)对应的记录ID(或唯一标识)。 2. 然后根据这些记录ID去查询详细的资产信息。 具体改写如下: 步骤1:创建子查询获取每个分组的最新记录ID 注意:由于原表结构未明确主键,这里假设t1表有主键id。如果没有,则需要根据实际情况调整。 由于原查询涉及多个表连接,且条件复杂,我们采用以下策略: 子查询1:获取每个分组下最新create_time对应的t1.id(假设t1.id是主键) SELECT t5.categoryName, t5.`NAME`, t5.model, t1.management_dept_id, MAX(t1.create_time) AS max_create_time FROM asset_escrow_ledger t1 LEFT JOIN ... (与之前相同的连接) WHERE ... (与之前相同的条件) GROUP BY t5.categoryName, t5.`NAME`, t5.model, t1.management_dept_id 但是,这样只能得到每个分组的最新时间,如果同一分组同一时间有多条记录,则无法区分。因此,我们使用相关子查询来获取主键。 改进:如果存在同一时间多条记录,我们取其中任意一条(比如最大id) SELECT t5.categoryName, t5.`NAME`, t5.model, t1.management_dept_id, MAX(t1.id) AS latest_id -- 假设id越大代表记录越新 FROM asset_escrow_ledger t1 ... (连接条件不变) WHERE inventory_id=7 AND ledger_id IN (...) GROUP BY t5.categoryName, t5.`NAME`, t5.model, t1.management_dept_id 注意:这个方法假设id越大则记录越新。如果实际情况不是这样(比如create_time相同,但id不是按时间顺序生成的),则需要使用其他方法。 步骤2:将上面的子查询结果与原表连接,获取所有字段 完整SQL如下: ```sql SELECT t5.categoryName, t5.`NAME`, t5.model, t1.standard_asset_id, t1.management_dept_id, t1.user_dept_id, t1.user_id, t1.provider_flag, ROUND(t1.price, 2) AS price, -- 这里已经是分组内最新记录的价格(因为通过子查询已经定位到最新记录) t1.position_id, t2.account_num AS num, t1.num AS amount, t2.remarks, t1.purchase_date, t2.first_inventory_num AS inventory_num, t2.second_inventory_num AS secondInventoryNum, (t2.account_num - t2.first_inventory_num) AS firstInventoryWinAndLossNum, (t2.account_num - t2.second_inventory_num) AS secondInventoryWinAndLossNum, ROUND(((t2.account_num - t2.first_inventory_num) * t1.price), 2) AS firstInventoryAmount, ROUND(((t2.account_num - t2.second_inventory_num) * t1.price), 2) AS secondInventoryAmount FROM asset_escrow_ledger t1 LEFT JOIN asset_escrow_company_inventory_ledger t2 ON t1.id = t2.ledger_id LEFT JOIN ( SELECT t1.id, t1.NAME, t1.model, t1.unit, t1.category_id, t1.manufacturer_id, t2.NAME AS childCategoryName, t3.NAME AS categoryName, t4.NAME AS parentCategoryName FROM `asset_standard_asset` t1 LEFT JOIN asset_category t2 ON t1.category_id = t2.id LEFT JOIN asset_category t3 ON t2.parent_id = t3.id LEFT JOIN asset_category t4 ON t3.parent_id = t4.id WHERE t1.data_type = 'escrow' ) t5 ON t1.standard_asset_id = t5.id -- 加入子查询,只选取最新记录 INNER JOIN ( SELECT t5_inner.categoryName, t5_inner.`NAME`, t5_inner.model, t1_inner.management_dept_id, MAX(t1_inner.id) AS latest_id -- 假设id越大越新 FROM asset_escrow_ledger t1_inner LEFT JOIN asset_escrow_company_inventory_ledger t2_inner ON t1_inner.id = t2_inner.ledger_id LEFT JOIN ( SELECT t1.id, t1.NAME, t1.model, t2.NAME AS childCategoryName, t3.NAME AS categoryName, t4.NAME AS parentCategoryName FROM `asset_standard_asset` t1 LEFT JOIN asset_category t2 ON t1.category_id = t2.id LEFT JOIN asset_category t3 ON t2.parent_id = t3.id LEFT JOIN asset_category t4 ON t3.parent_id = t4.id WHERE t1.data_type = 'escrow' ) t5_inner ON t1_inner.standard_asset_id = t5_inner.id WHERE t2_inner.inventory_id = 7 AND t2_inner.ledger_id IN (26580, 26596, ...) -- 同样的ID列表 GROUP BY t5_inner.categoryName, t5_inner.`NAME`, t5_inner.model, t1_inner.management_dept_id ) AS latest_records ON t1.id = latest_records.latest_id -- 通过主键连接 WHERE t2.inventory_id = 7 AND t2.ledger_id IN (26580, 26596, ...) -- 同样的ID列表 ``` 注意:这个查询中,我们使用了内连接(INNER JOIN)来只获取每个分组的最新记录。同时,原WHERE条件中的inventory_idledger_id条件在子查询主查询中都需要出现,以确保数据范围一致。 但是,这个查询有一个潜在问题:子查询中重复了主查询的连接条件,导致SQL冗长且可能性能下降。另外,如果id最大的记录并不代表最新(比如create_time更大),那么我们需要调整子查询。 如果不能用id,而是用create_time,那么我们需要先按分组获取最大create_time,然后再获取该时间对应的最大id(如果有多个),这样更准确: ```sql SELECT t5_inner.categoryName, t5_inner.`NAME`, t5_inner.model, t1_inner.management_dept_id, MAX(t1_inner.create_time) AS max_create_time, MAX(t1_inner.id) AS latest_id -- 在最大create_time下取最大id FROM ... -- 同上 GROUP BY ... ``` 然后,在子查询中,我们需要再关联一次来获取这个最大create_time对应的记录(因为直接取MAX(id)可能不是该时间下所有记录中的一条)。但是这样会变得更复杂。 因此,我们采用两步法: 子查询1:先得到每个分组的最新时间对应的最大id(用于打破平局) 子查询2:再根据这个结果去关联原表。 但这样会使得SQL非常复杂。考虑到性能,如果数据量不大,可以使用以下方式: 方法二:使用派生表用户变量模拟ROW_NUMBER(适用于MySQL 5.7) 鉴于复杂度,如果数据量允许,建议使用第一种方法(假设id越大越新)来简化。 总结:错误1064主要是由于MySQL版本不支持命名窗口函数(WINDOW子句)导致。请根据您的MySQL版本选择合适的方案。 如果您的MySQL是8.0以上版本,请检查窗口函数定义是否有其他语法错误(比如括号不匹配等)。我们提供的窗口函数示例在MySQL 8.0中应该是可用的,但请注意窗口定义中不能有语法错误。 窗口函数版本修正(不使用命名窗口): 如果不想使用命名窗口,可以每个窗口函数都写完整的OVER子句: ```sql SELECT * FROM ( SELECT t5.categoryName, t5.`NAME`, t5.model, t1.standard_asset_id, t1.management_dept_id, t1.user_dept_id, t1.user_id, t1.provider_flag, FIRST_VALUE(t1.price) OVER ( PARTITION BY t5.categoryName, t5.`NAME`, t5.model, t1.management_dept_id ORDER BY t1.create_time DESC ) AS latest_price, ..., ROW_NUMBER() OVER ( PARTITION BY t5.categoryName, t5.`NAME`, t5.model, t1.management_dept_id ORDER BY t1.create_time DESC ) AS rn FROM ... WHERE ... ) AS sub WHERE rn=1; ``` 这样就去掉了WINDOW子句,避免了命名窗口的语法。 请根据实际情况选择解决方案。 §§相关问题§§ 1. 如何查询MySQL服务器的版本以确定是否支持窗口函数? 2. 当分组内存在多条记录具有相同的最新create_time时,如何确保只选择其中一条记录? 3. 在低版本MySQL中,除了使用子查询GROUP BY,还有哪些方法可以模拟窗口函数ROW_NUMBER()? 4. 在窗口函数版本中,如果create_time字段存在NULL值,会对排序产生什么影响?如何避免? 5. 如何优化包含大量IN列表多个JOIN的子查询性能?</think>### MySQL语法错误分析及解决方案 您遇到的错误是MySQL的语法错误提示: ``` 1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '( PARTITION BY t5.categoryName, t5.`NAME`, t5.model, t1.management_dept_id ' at line 11 ``` ### 错误原因分析 1. **MySQL版本兼容性问题**(最常见原因): - `WINDOW`子句是MySQL 8.0+才支持的语法 - 如果您的MySQL版本低于8.0(如5.7或更早),会直接报此语法错误 2. **语法结构错误**: - 窗口函数定义位置不正确 - 缺少必要的关键字或括号 - 窗口定义与其他子句冲突 ### ✅ 解决方案 #### 方案1:升级MySQL到8.0+(推荐) ```bash # Ubuntu示例 sudo apt update sudo apt install mysql-server-8.0 ``` #### 方案2:修改为MySQL 5.7兼容版本(去掉WINDOW子句) ```sql SELECT * FROM ( SELECT t5.categoryName, t5.`NAME`, t5.model, t1.standard_asset_id, t1.management_dept_id, t1.user_dept_id, t1.user_id, t1.provider_flag, -- 直接在每个窗口函数中定义PARTITION BY FIRST_VALUE(t1.price) OVER ( PARTITION BY t5.categoryName, t5.`NAME`, t5.model, t1.management_dept_id ORDER BY t1.create_time DESC ) AS latest_price, ROW_NUMBER() OVER ( PARTITION BY t5.categoryName, t5.`NAME`, t5.model, t1.management_dept_id ORDER BY t1.create_time DESC ) AS rn -- ... 其余部分保持不变 ... ) AS sub WHERE rn = 1; ``` #### 方案3:完全兼容MySQL 5.7的写法(使用子查询) ```sql SELECT t5.categoryName, t5.`NAME`, t5.model, t1.standard_asset_id, t1.management_dept_id, -- 获取最新价格的子查询 (SELECT price FROM asset_escrow_ledger WHERE standard_asset_id = t1.standard_asset_id AND management_dept_id = t1.management_dept_id ORDER BY create_time DESC LIMIT 1) AS latest_price, -- ... 其余字段 ... FROM asset_escrow_ledger t1 -- ... 连接条件WHERE条件 ... ``` ### 关键修改点说明 1. **移除WINDOW子句**: - 将窗口定义直接嵌入每个窗口函数中 - 避免使用`WINDOW w AS (...)` 2. **保持PARTITION BY结构**: - 确保分区字段与原始分组一致 - 保持`ORDER BY create_time DESC`排序 3. **兼容性验证**: - 方案2适用于MySQL 8.0+但不需要命名窗口 - 方案3完全兼容MySQL 5.5+所有版本 ### 版本检查命令 ```sql -- 执行此SQL查看MySQL版本 SELECT VERSION(); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值