技术周总结 2024.07.22~07.28周日(Java Tidb Mysql)

一、 07.23 周二

1.1)问题01:下面的java代码会发生NPE吗?String aa = "ss: "; String bb = null; aa + bb;

在 Java 中,字符串的连接操作(使用 + 运算符)对 null 值有特殊处理。如果你将一个 String 对象与 null 连接,null 会被转换为字符串 "null"。因此,下面的代码不会发生 NullPointerException (NPE)。

String aa = "ss: ";
String bb = null;
aa + bb;

解释

  • aa 是一个字符串 "ss: "
  • bbnull

当执行字符串连接操作 aa + bb 时,null 会被转换为字符串 "null",结果是 "ss: null"

完整示例

public class Main {
    
    
    public static void main(String[] args) {
    
    
        String aa = "ss: ";
        String bb = null;
        String result = aa + bb;
        System.out.println(result); // 输出 "ss: null"
    }
}

输出

ss: null

总结

在上述代码中,aa + bb 不会引发 NullPointerException。相反,null 会被转换为字符串 "null",并连接到字符串 aa 上。

1.2)问题02:Spring注解@ControllerAdvice 具体的使用方法

@ControllerAdvice 是 Spring MVC 提供的一个注解,用于统一处理控制器中抛出的异常。通过在一个类上添加 @ControllerAdvice 注解,这个类就成为全局异常处理类,可以针对不同的异常类型进行处理。

具体的使用方法如下:

  1. 创建一个类并添加 @ControllerAdvice 注解。
  2. 在类中定义异常处理方法,可以使用 @ExceptionHandler 注解来指定要处理的异常类型。
  3. 在异常处理方法中编写具体的异常处理逻辑,比如返回错误信息、跳转到错误页面等。

示例代码如下:

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

@ControllerAdvice
public class GlobalExceptionHandler {
    
    

    @ExceptionHandler(Exception.class)
    @ResponseBody
    public String handleException(Exception e) {
    
    
        return "发生异常:" + e.getMessage();
    }

    @ExceptionHandler(MyCustomException.class)
    public String handleCustomException(MyCustomException e) {
    
    
        return "自定义异常:" + e.getMessage();
    }
}

在上面的示例中,GlobalExceptionHandler 类使用 @ControllerAdvice 注解标记为全局异常处理类,定义了两个异常处理方法。第一个方法处理所有类型的异常,将异常信息返回给前端;第二个方法处理自定义异常 MyCustomException,并返回自定义的错误信息。

这样,在控制器中抛出异常时,Spring MVC 就会自动调用对应的异常处理方法进行处理。这样可以统一处理异常,使代码更加健壮和可维护。

1.3) 问题03: tidb中查询长时间运行的sql

SELECT * FROM INFORMATION_SCHEMA.PROCESSLIST WHERE DB = 'my_database' AND COMMAND != 'Sleep';
show processlist;

杀死 运行的查询的id

kill tidb queryId;

1.3.1)怎么杀死tidb当前实例 INFORMATION_SCHEMA.PROCESSLIST 中看不到,但是 整个集群 INFORMATION_SCHEMA.CLUSTER_PROCESSLIST 能看到的 活动会话呢?

在 TiDB 集群中,有时会遇到这种情况:某个活动会话在 INFORMATION_SCHEMA.PROCESSLIST 中看不到,但在 INFORMATION_SCHEMA.CLUSTER_PROCESSLIST 中可以看到。这通常是因为该会话在另一个 TiDB 实例上运行。

要终止这种会话,可以按照以下步骤进行操作:

1. 查找目标会话

首先,通过 INFORMATION_SCHEMA.CLUSTER_PROCESSLIST 找到目标会话,并获取其所在的 TiDB 实例。

SELECT * FROM INFORMATION_SCHEMA.CLUSTER_PROCESSLIST WHERE Id = 123;

假设返回的结果中包含以下重要信息:

  • ID: 123
  • USER: your_user
  • HOST: your_host
  • DB: your_db
  • COMMAND: Query
  • TIME: 100
  • STATE: executing
  • INFO: your_query
  • TIDB_SERVER: 10.0.0.1:4000 (假设会话在这个 TiDB 实例上)

2. 连接到目标 TiDB 实例

使用 mysql 客户端或其他数据库连接工具,连接到返回结果中 TIDB_SERVER 所在的 TiDB 实例。

mysql -h 10.0.0.1 -P 4000 -u your_user -p

3. 终止会话

连接到目标 TiDB 实例后,使用 KILL 命令终止该会话:

KILL 123;

4. 验证终止结果

再次查询 INFORMATION_SCHEMA.CLUSTER_PROCESSLIST,确保会话已经被终止:

SELECT * FROM INFORMATION_SCHEMA.CLUSTER_PROCESSLIST WHERE Id = 123;

如果会话已经被成功终止,那么该查询将不返回任何结果。

示例流程

以下是一个完整的示例流程:

-- 步骤 1: 查找目标会话
SELECT * FROM INFORMATION_SCHEMA.CLUSTER_PROCESSLIST WHERE Id = 123;

假设返回结果如下:

+-----+----------+-----------+---------+---------+------+-----------+------------+---------------+
| ID  | USER     | HOST      | DB      | COMMAND | TIME | STATE     | INFO       | TIDB_SERVER   |
+-----+----------+-----------+---------+---------+------+-----------+------------+---------------+
| 123 | your_user| your_host | your_db | Query   | 100  | executing | your_query | 10.0.0.1:4000 |
+-----+----------+-----------+---------+---------+------+-----------+------------+---------------+
-- 步骤 2: 连接到目标 TiDB 实例
mysql -h 10.0.0.1 -P 4000 -u your_user -p
-- 步骤 3: 终止会话
KILL 123;
-- 步骤 4: 验证终止结果
SELECT * FROM INFORMATION_SCHEMA.CLUSTER_PROCESSLIST WHERE Id = 123;

通过这种方式,你可以在 TiDB 集群环境中有效地管理和终止跨实例的活动会话。

二、07.25 周四

2.1)问题01: 怎么修改 mysql表中的某一列的值为 一些自增的数字:

你可以使用以下的 SQL 语句来修改 MySQL 表中某一列的值为一些自增的数字:

SET @row_number = 0;
UPDATE your_table_name
SET template_no = (@row_number:=@row_number+1);

在上面的 SQL 语句中,首先通过设置变量 @row_number 来记录自增的数字,然后通过 UPDATE 语句将表中的 template_no 列的值更新为自增的数字。

三、07.27 周六

3.1)问题01: mysql执行命令行,怎么保证终端关闭了,能继续执行mysql的相关命令?

要在 MySQL 中执行命令并确保即使在终端关闭后这些命令也能继续运行,您可以使用几种不同的方法。这里有一些推荐的策略:

1. 使用 nohup 命令

nohup 命令可以让您启动一个进程,并且即使您退出 shell 或者终端关闭,该进程也会继续运行。

示例:
nohup mysql -u username -p password -e "your_mysql_command" &
  • nohup: 表示不挂断。
  • &: 表示将命令放到后台执行。
查看输出:

nohup 运行的命令的标准输出会被重定向到 nohup.out 文件中(默认位置是当前目录)。

2. 使用 screentmux 会话管理器

screentmux 是两个流行的会话管理工具,可以在其中创建多个终端会话,并且即使客户端断开连接或终端关闭,这些会话中的进程仍然继续运行。

示例:
使用 screen:
screen
mysql -u username -p password -e "your_mysql_command"

Ctrl+A 后再按 D 可以分离 session 而不会关闭它。

使用 tmux:
tmux new -s mysession
mysql -u username -p password -e "your_mysql_command"

Ctrl+B 后再按 D 可以分离 session 而不会关闭它。

3. 使用计划任务 (Cron Jobs)

如果您希望定期执行 MySQL 命令,可以使用 cron jobs。

示例:
crontab -e

然后添加一行类似下面的内容:

* * * * * mysql -u username -p password -e "your_mysql_command"

4. 使用 systemd 服务

如果您的系统支持 systemd,您可以创建一个新的服务单元文件来持续运行 MySQL 命令。

示例:

创建一个新的 .service 文件:

sudo nano /etc/systemd/system/mysqlcommand.service

然后添加以下内容:

[Unit]
Description=MySQL Command Service

[Service]
ExecStart=/usr/bin/mysql -u username -p password -e "your_mysql_command"

[Install]
WantedBy=default.target

接着启用并启动服务:

sudo systemctl enable mysqlcommand.service
sudo systemctl start mysqlcommand.service

以上方法可以根据您的具体需求选择合适的方式。如果只是简单的定时任务,建议使用 cron jobs;如果需要长时间运行的任务并且需要管理,则可以考虑使用 screentmux;如果是系统级的服务,则可以考虑使用 systemd

这样的命令,会导致终端关闭时,运行关闭:

nohup mysql -u username -p password -e "your_mysql_command" > output-2.log 2>&1 &

修改为

nohup mysql -u username -p password -e "your_mysql_command"  &

即可
这样在别的 终端中,ps aux|grep mysql 可以看到这个执行的命令

四、07.28 周日

4.1) 问题01: 哪些因素会导致linux中的进程进入sleep状态,怎么解决

在Linux系统中,进程可能处于多种状态之一,其中包括睡眠状态(Sleep)。进程进入睡眠状态通常意味着它正在等待某种资源或条件变得可用。以下是可能导致进程进入睡眠状态的一些常见因素以及相应的解决方法:

导致进程进入睡眠状态的因素:

  1. 等待I/O操作完成

    • 如果一个进程正在进行磁盘读写或其他I/O操作,并且该操作还没有完成,进程将进入睡眠状态。
    • 解决方法:优化I/O操作,比如使用更快的硬盘驱动器、增加缓存等。
  2. 等待锁或信号量

    • 当进程试图获取已经被另一个进程锁定的资源时,它会进入睡眠状态直到资源可用。
    • 解决方法:确保锁的使用是正确的,并尽量减少锁的持有时间;考虑使用更高效的同步机制。
  3. 等待用户输入

    • 如果一个程序正在等待用户的键盘输入或其他交互式输入,它会进入睡眠状态。
    • 解决方法:优化用户界面设计,提高用户体验,减少不必要的等待时间。
  4. 等待网络连接

    • 如果进程正在等待网络数据包或响应,它也会进入睡眠状态。
    • 解决方法:检查网络连接状况,优化网络代码,使用超时设置防止无限期等待。
  5. 等待定时器到期

    • 使用select(), poll(), epoll_wait(), 或者 sleep()等函数可以让进程进入睡眠状态直到某个事件发生或某个时间点到达。
    • 解决方法:合理设置定时器的超时时间,避免不必要的长时间等待。
  6. 等待资源可用

    • 比如等待内存分配或等待某些系统资源变得可用。
    • 解决方法:优化资源管理,确保有足够的资源可用,或采用更好的资源分配策略。

解决方法:

  1. 优化资源使用

    • 对于等待I/O操作的情况,可以尝试使用异步I/O(如aio_read(), aio_write(), 或libaio)来提高效率。
    • 考虑使用多线程或多进程模型来允许其他任务在等待资源时继续执行。
  2. 改进算法和逻辑

    • 重新审视程序的算法和逻辑,看是否有优化的空间。
    • 确保所有必要的资源都在适当的时间点准备好。
  3. 使用超时

    • 在可能的情况下,为等待操作设置合理的超时时间,这样进程就不会无限期地阻塞。
  4. 监控和调试

    • 使用系统监控工具(如top, htop, ps等)来监控进程状态。
    • 使用调试工具(如gdb)来深入了解进程为何进入睡眠状态。
  5. 调整系统配置

    • 根据需要调整系统的调度策略和优先级。
    • 调整内核参数以优化性能。

通过上述方法,你可以有效地诊断和解决导致进程进入睡眠状态的问题。如果问题持续存在,你可能还需要深入调查程序的实现细节和系统配置。

猜你喜欢

转载自blog.csdn.net/xinkuaile/article/details/140633983